home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-12-13 | 194.4 KB | 6,539 lines | [TEXT/MPS ] |
- /*------------------------------------------------------------------------------
-
- File: DrawEditor.cpp
-
- Written by: Dave Stafford based on SamplePart
-
- Copyright: © 1995 by Apple Computer, Inc., all rights reserved.
-
- Description: DrawEditor demonstrates a fairly complete editor which supports
- native content, linking, embedding, & scripting.
-
-
- Demonstrates: The following recipes were used in implementing the
- DrawEditor:
- 1. Open
- 2. Adding A Display Frame
- 3. Adding A Facet
- 4. Part Drawing
- 5. Refcounting Geometry
- 6. ViewTypes & Presentations
- 7. Display Frame 'ternalization
- 8. Part Init & Externalization
- 9. Part Init & partWrapper
- 10. Part Storage Model
- 11. Persistent Reference
- 12. RefCounting
- 13. Storage Unit
- 14. Activation
- 15. Basic Event Handling
- 16. Menus
- 17. Windows & Dialogs
- 18. Exception Handling
- 19. Memory Manager
- 20. Using Resources
-
-
-
- Known Problems: <hee hee>
-
- Notes: • For methods where it is necessary to call the parent class
- implementation, the calls are made from the SOM class. See
- som_SamplePart.cpp and the Class Reference to know whether
- you need to call the parent class from any method.
-
- ------------------------------------------------------------------------------*/
-
- // Profiling
- #ifdef qProfileDrawEditor
- #include <profiler.h>
- #endif
-
- // -- Compiler/Preprocessor Switches --
-
- #ifndef _COMPILERDEFS_
- #include "CompDefs.h"
- #endif
-
- // -- OpenDoc Utilities --
-
- #ifndef _EXCEPT_
- // Exceptions define several important macros (ie. CHECKENV)
- // which are used in the SOM method dispatch glue. If Except.h
- // is not included early enough, exceptions may not be thrown
- // correctly when returning from a SOM method with "ev" parameter set.
- #include <Except.h>
- #endif
-
- // -- DrawEditor Includes --
-
- #ifndef _DRAWEDITORCONSTANTS_
- #include "DrawEditorConstants.h"
- #endif
-
- #ifndef _DRAWEDITORUTILS_
- #include "DrawEditorUtils.h"
- #endif
-
- #ifndef _DRAWEDITORDEF_
- #include "DrawEditorDef.h"
- #endif
-
- #ifndef _DRAWEDTORUTILS_
- #include "DrawEditorUtils.h"
- #endif
-
- #ifndef _DrawEditor_
- #include "DrawEditor.h"
- #endif
-
- #ifndef _FRAMEPROXY_
- #include "FrameProxy.h"
- #endif
-
- #ifndef _PROMISE_
- #include "Promise.h"
- #endif
-
- #ifndef _SELECTION_
- #include "Selection.h"
- #endif
-
- #ifndef _SHAPECOMMANDS_
- #include "ShapeCommands.h"
- #endif
-
- #ifndef _LINKCOMMANDS_
- #include "LinkCommands.h"
- #endif
-
- #ifndef _SHAPES_
- #include "Shapes.h"
- #endif
-
- #ifndef _LINK_
- #include "Link.h"
- #endif
-
- #ifndef _PALETTE_
- #include "Palette.h"
- #endif
-
- // -- OpenDoc Includes --
-
- #ifndef _ODTYPES_
- #include <ODTypes.h>
- #endif
-
- #ifndef SOM_Module_OpenDoc_Global_Types_defined // For kODPresDefault
- #include <ODTypesM.xh>
- #endif
-
- #ifndef SOM_ODPart_xh
- #include <Part.xh>
- #endif
-
- #ifndef SOM_ODTranslation_xh
- #include <Translt.xh>
- #endif
-
- #ifndef SOM_ODFacetIterator_xh
- #include <FacetItr.xh>
- #endif
-
- #ifndef SOM_ODFacet_xh
- #include <Facet.xh>
- #endif
-
- #ifndef SOM_ODClipboard_xh
- #include <Clipbd.xh>
- #endif
-
- #ifndef SOM_ODDragItemIterator_xh
- #include <DgItmIt.xh>
- #endif
-
- #ifndef SOM_ODDragAndDrop_xh
- #include <DragDrp.xh>
- #endif
-
- #ifndef SOM_ODDragAndDrop_xh
- #include <DragDrp.xh>
- #endif
-
- #ifndef SOM_ODFrame_xh
- #include <Frame.xh>
- #endif
-
- #ifndef SOM_ODFrameFacetIterator_xh
- #include <FrFaItr.xh>
- #endif
-
- #ifndef SOM_ODArbitrator_xh
- #include <Arbitrat.xh>
- #endif
-
- #ifndef SOM_Module_OpenDoc_Foci_defined
- #include <Foci.xh>
- #endif
-
- #ifndef SOM_ODShape_xh
- #include <Shape.xh>
- #endif
-
- #ifndef SOM_Module_OpenDoc_StdProps_defined
- #include <StdProps.xh>
- #endif
-
- #ifndef SOM_Module_OpenDoc_StdTypes_defined
- #include <StdTypes.xh>
- #endif
-
- #ifndef SOM_Module_OpenDoc_StdDefs_defined
- #include <StdDefs.xh>
- #endif
-
- #ifndef SOM_Module_OpenDoc_Commands_defined
- #include <CmdDefs.xh>
- #endif
-
- #ifndef SOM_ODDraft_xh
- #include <Draft.xh>
- #endif
-
- #ifndef SOM_ODStorageUnit_xh
- #include <StorageU.xh>
- #endif
-
- #ifndef SOM_ODStorageUnitView_xh
- #include <SUView.xh>
- #endif
-
- #ifndef SOM_ODLinkSrc_xh
- #include <LinkSrc.xh>
- #endif
-
- #ifndef SOM_ODLink_xh
- #include <Link.xh>
- #endif
-
- #ifndef SOM_ODTransform_xh
- #include <Trnsform.xh>
- #endif
-
- #ifndef SOM_ODFocusSet_xh
- #include <FocusSet.xh>
- #endif
-
- #ifndef SOM_ODMenuBar_xh
- #include <MenuBar.xh>
- #endif
-
- #ifndef SOM_ODWindow_xh
- #include <Window.xh>
- #endif
-
- #ifndef SOM_ODWindowState_xh
- #include <WinStat.xh>
- #endif
-
- #ifndef SOM_ODCanvas_xh
- #include <Canvas.xh>
- #endif
-
- #ifndef SOM_ODSession_xh
- #include <ODSessn.xh>
- #endif
-
- // -- OpenDoc Utilities --
-
- #ifndef _NMSPCUTL_
- #include <NmSpcUtl.h>
- #endif
-
- #ifndef _BNDNSUTL_
- #include <BndNSUtl.h>
- #endif
-
- #ifndef _STDTYPIO_
- #include <StdTypIO.h>
- #endif
-
- #ifndef SOM_ODInfo_xh
- #include <Info.xh>
- #endif
-
- #ifndef _TEMPOBJ_
- #include <TempObj.h>
- #endif
-
- #ifndef _TEMPITER_
- #include <TempIter.h>
- #endif
-
- #ifndef _ODUTILS_
- #include <ODUtils.h>
- #endif
-
- #ifndef _STDTYPIO_
- #include <StdTypIO.h>
- #endif
-
- #ifndef _ORDCOLL_
- #include "OrdColl.h"
- #endif
-
- #ifndef _ODDEBUG_
- #include <ODDebug.h>
- #endif
-
- #ifndef _ITEXT_
- #include <IText.h>
- #endif
-
- #ifndef _FOCUSLIB_
- #include <FocusLib.h>
- #endif
-
- #ifndef _USERSRCM_
- #include <UseRsrcM.h>
- #endif
-
- #ifndef _ODMEMORY_
- #include <ODMemory.h>
- #endif
-
- #ifndef _ISOSTR_
- #include <ISOStr.h>
- #endif
-
- #ifndef _PLFMDEF_
- #include <PlfmDef.h>
- #endif
-
- #ifndef _PASCLSTR_
- #include <PasclStr.h>
- #endif
-
- #ifndef _STORUTIL_
- #include <StorUtil.h>
- #endif
-
- #ifndef _WINUTILS_
- #include <WinUtils.h>
- #endif
-
- #ifndef _UTILERRS_
- #include <UtilErrs.h>
- #endif
-
- // -- Macintosh Includes --
-
- #ifndef __ERRORS__
- #include <Errors.h>
- #endif
-
- #ifndef __RESOURCES__
- #include <Resources.h>
- #endif
-
- #ifndef __DIALOGS__
- #include <Dialogs.h>
- #endif
-
- #ifndef __TOOLUTILS__
- #include <ToolUtils.h>
- #endif
-
- #ifndef __ICONS__
- #include <Icons.h>
- #endif
-
- #ifndef __QUICKDRAW__
- #include <Quickdraw.h>
- #endif
-
- #ifndef __LOWMEM__
- #include <LowMem.h>
- #endif
-
- #ifndef mathRoutinesIncludes
- #include <math routines.h>
- #endif
-
- #pragma segment DrawEditor
-
- //==============================================================================
- // DrawEditor
- //==============================================================================
-
- //------------------------------------------------------------------------------
- // Method: Constructor
- // Origin: DrawEditor
- //
- // Description: This is the C++ class constructor.
- //
- // Warnings: You are not allowed to throw an exception from this
- // method.
- //------------------------------------------------------------------------------
-
- DrawEditor::DrawEditor()
- {
- SOM_Trace("DrawEditor","somInit");
-
- fGroupCount = 0L;
- fShapeList = kODNULL;
- fEmbeddedFrames = kODNULL;
- fHilightedDragFacet = kODNULL;
- fActiveBorderShape = kODNULL;
-
- fDisplayFrameProxies= kODNULL;
- fDirty = kODFalse;
- fSelf = kODNULL;
- fReadOnlyStorage = kODFalse;
- fLinkStatus = kODNotInLink;
-
- fSelection = kODNULL;
-
- fPendingPublish = kODNULL;
- fPendingDragPublish = kODNULL;
-
- fPublishLinks = kODNULL;
- fSubscribeLinks = kODNULL;
-
- fPartContent = kODNULL;
-
- }
-
- //------------------------------------------------------------------------------
- // Method: Destructor
- // Origin: DrawEditor
- //
- // Description: This is the SOM equivalent of a C++ class destructor.
- // In this routine, you should clean up any class members
- // which were not cleaned up in the ReleaseAll and
- // Release methods; and finally call you parent class's
- // somUninit (destructor) method.
- //
- // Warnings: You are not allowed to throw an exception from this
- // method.
- //------------------------------------------------------------------------------
-
- DrawEditor::~DrawEditor()
- {
- SOM_Trace("DrawEditor","somUninit");
-
- // Delete the current selection
- if (fSelection)
- delete fSelection;
-
- // Delete the shape list
- if (fShapeList)
- delete fShapeList;
-
- // Delete the shape list
- if (fEmbeddedFrames)
- delete fEmbeddedFrames;
-
- // Delete the subscribe links
- if (fSubscribeLinks)
- delete fSubscribeLinks;
-
- // Delete the publish links;
- if (fPublishLinks)
- delete fPublishLinks;
-
- // Delete the content object
- if (fPartContent)
- delete fPartContent;
- }
-
- //------------------------------------------------------------------------------
- // Method: GetODPart
- // Origin: DrawEditor
- //
- // Description: Return the part wrapper of the ODPart whose implementation is
- // provided by this class.
- //
- // Warnings:
- //------------------------------------------------------------------------------
-
- ODPart* DrawEditor::GetODPart() const
- {
- return fSelf;
- }
-
- //------------------------------------------------------------------------------
- // Method: GetEditorKind
- // Origin: DrawEditor
- //
- // Description: Return the ODValuType representing the type of data we edit.
- //
- // Warnings:
- //------------------------------------------------------------------------------
-
- ODValueType DrawEditor::GetEditorKind() const
- {
- return kDrawEditorKind;
- }
-
- //------------------------------------------------------------------------------
- // Method: GetEditorKind
- // Origin: DrawEditor
- //
- // Description: Return the current Link Status.
- //
- // Warnings:
- //------------------------------------------------------------------------------
-
- ODLinkStatus DrawEditor::GetLinkStatus() const
- {
- return fLinkStatus;
- }
-
- //------------------------------------------------------------------------------
- // Method: IsReadOnly
- // Origin: DrawEditor
- //
- // Description: Return a reference to the current session.
- //
- //------------------------------------------------------------------------------
-
- ODBoolean DrawEditor::IsReadOnly()
- {
- return fReadOnlyStorage;
- }
-
-
- //------------------------------------------------------------------------------
- // Method: GetSession
- // Origin: DrawEditor
- //
- // Description: Return a reference to the current session.
- //
- //------------------------------------------------------------------------------
-
- ODSession* DrawEditor::GetSession(Environment* ev) const
- {
- ODPart* tPart = GetODPart();
- ODStorageUnit* tStorage = tPart->GetStorageUnit(ev);
- ODSession* tSession = tStorage->GetSession(ev);
-
- return tSession;
- }
-
-
- //------------------------------------------------------------------------------
- // Method: GetDraft
- // Origin: DrawEditor
- //
- // Description: Return a reference to this part's draft.
- //
- //------------------------------------------------------------------------------
-
- ODDraft* DrawEditor::GetDraft(Environment* ev) const
- {
- return GetODPart()->GetStorageUnit(ev)->GetDraft(ev);
- }
-
-
- //------------------------------------------------------------------------------
- // Method: GetShapeList
- // Origin: DrawEditor
- //
- // Description: Return a list of my shapes.
- //
- //------------------------------------------------------------------------------
-
- COrderedList* DrawEditor::GetShapeList() const
- {
- return fShapeList;
- }
-
-
- //------------------------------------------------------------------------------
- // Method: GetEmbeddedFrames
- // Origin: DrawEditor
- //
- // Description: Return a list of my embeddedFrames.
- //
- //------------------------------------------------------------------------------
-
- COrderedList* DrawEditor::GetEmbeddedFrames() const
- {
- return fEmbeddedFrames;
- }
-
-
- //------------------------------------------------------------------------------
- // Method: GetFirstSourceFrame
- // Origin: DrawEditor
- //
- // Description:
- //------------------------------------------------------------------------------
- ODFrame* DrawEditor::GetFirstSourceFrame (Environment* ev)
- {
- if ( fDisplayFrameProxies )
- {
- COrdListIterator fiter(fDisplayFrameProxies);
- for ( CDisplayFrameProxy* frameProxy = (CDisplayFrameProxy*)fiter.First();
- fiter.IsNotComplete();
- frameProxy=(CDisplayFrameProxy*)fiter.Next())
- {
- // This will cause the frame to internalize
- ODFrame* frame = frameProxy->GetFrame(ev);
- CFrameInfo* info = (CFrameInfo*) frame->GetPartInfo(ev);
-
- if (( frame->GetPresentation(ev) == gGlobals->fMainPresentation ) &&
- ( frame->GetViewType(ev) == gGlobals->fFrameView )&&!info->HasSourceFrame())
- {
- return frame;
- }
- }
- }
- return kODNULL;
- }
-
-
- //------------------------------------------------------------------------------
- // Method: GetANYFrame
- // Origin: DrawEditor
- //
- // Description: Since frames have ceratin facilities ( namely object factory
- // methods ) there are times that having guaranteed access to ANY frame is
- // necessary.
- //------------------------------------------------------------------------------
-
- ODFrame* DrawEditor::GetANYFrame(Environment* ev) const
- {
- if ( fDisplayFrameProxies )
- {
- COrdListIterator fiter(fDisplayFrameProxies);
- for ( CDisplayFrameProxy* frameProxy = (CDisplayFrameProxy*)fiter.First();
- fiter.IsNotComplete();
- frameProxy=(CDisplayFrameProxy*)fiter.Next())
- {
- if (frameProxy->IsFrameInMemory())
- {
- return frameProxy->GetFrame(ev);
- }
- }
- }
-
- #ifdef ODDebug
- DebugStr("\p Didn't get a frame! Need to work harder..");
- #endif
-
- return kODNULL;
- }
-
-
- //------------------------------------------------------------------------------
- // Method: GetContentDisplayFrames
- // Origin: DrawEditor
- //
- // Description: Return a list of the frames whose presentation is
- // gGlobals->fMainPresentation AND whose view type is frame.
- //
- // This method is useful for when the part, or a client of the editor needs access
- // to just the display frames of the editor which are currently displaying content.
- //
- // NOTE: The caller must delete the list pointer ( not the links ) that is returned.
- //------------------------------------------------------------------------------
-
- COrderedList* DrawEditor::GetContentDisplayFrames(Environment* ev) const
- {
- COrderedList* theList = kODNULL;
-
- if ( fDisplayFrameProxies )
- {
- COrdListIterator fiter(fDisplayFrameProxies);
- for ( CDisplayFrameProxy* frameProxy = (CDisplayFrameProxy*)fiter.First();
- fiter.IsNotComplete();
- frameProxy=(CDisplayFrameProxy*)fiter.Next())
- {
- // This will cause the frame to internalize
- ODFrame* frame = frameProxy->GetFrame(ev);
-
- if (( frame->GetPresentation(ev) == gGlobals->fMainPresentation ) &&
- ( frame->GetViewType(ev) == gGlobals->fFrameView ))
- {
- // Only create the list if we find any
- if (!theList)
- theList = new COrderedList;
-
- // Add the found frame to the list
- theList->AddLast(frame);
- }
- }
- }
-
- return theList;
- }
-
-
- //------------------------------------------------------------------------------
- // Method: GetGroupCount
- // Origin: DrawEditor
- //
- // Description: Return the last GroupID generated by this part instance.
- //------------------------------------------------------------------------------
-
- ODULong DrawEditor::GetGroupCount() const
- {
- return fGroupCount;
- }
-
- //------------------------------------------------------------------------------
- // Method: GetNewGroupID
- // Origin: DrawEditor
- //
- // Description: Return the next GroupID generated by this part instance.
- //------------------------------------------------------------------------------
-
- ODULong DrawEditor::GetNewGroupID()
- {
- fGroupCount++;
- return this->GetGroupCount();
- }
-
- //------------------------------------------------------------------------------
- // Method: GetRootFacetOfActiveWindow
- // Origin: DrawEditor
- //
- // Description: Return a reference to the root facet of the active window.
- //
- // This method is useful for when the part, or a client of the part needs access to
- // a factory method of facet and has no other access to facets.
- //------------------------------------------------------------------------------
-
- ODFacet* DrawEditor::GetRootFacetOfActiveWindow(Environment* ev) const
- {
- ODFacet* facet = kODNULL;
- TRY
- // Acquire the active window
- TempODWindow window = this->GetSession(ev)->GetWindowState(ev)->AcquireActiveWindow(ev);
- THROW_IF_NULL(window);
-
- facet = window->GetRootFacet(ev);
- CATCH_ALL
- #ifdef ODDebug
- DebugStr("\p Trouble getting root facet of active window!");
- #endif
- ENDTRY
-
- return facet;
- }
-
-
- //------------------------------------------------------------------------------
- // Method: InitPart
- // Origin: ODPart
- //
- // Description: This method is called when a new instance of this part
- // is being created. The part should write out all the
- // standard properties and values that the part expects
- // to see.
- //
- // Warning: It is not appropriate to require user interaction while
- // stationery is being created. Do not present the user
- // with error dialogs or splash screens from this method.
- //------------------------------------------------------------------------------
-
- void DrawEditor::InitPart( Environment* ev,
- ODStorageUnit* storageUnit,
- ODPart* partWrapper )
- {
- SOM_Trace("DrawEditor","InitPart");
-
- TRY
- // To allow editor swapping (translation) at runtime, OpenDoc requires
- // that we pass in a "reference" to ourselves when interacting with the
- // API (ie. WindowState::RegisterWindow(), Dispatcher::RegisterIdle, etc).
- // The "partWrapper" passed to us here and in InitPartFromStorage is the
- // "reference" OpenDoc is asking us to use.
- fSelf = partWrapper;
-
- // We are being created, either as part of generating stationery or
- // by some editor instantiating the part, so the destination storage
- // must be writeable.
- fReadOnlyStorage = kODFalse;
-
- // Call the common initialization code to get set up.
- this->Initialize(ev);
-
- // Since we have just been created, our state/content info has
- // never been written out, so setting our "dirty" flag will
- // give us a chance to do that.
-
- this->SetDirty(ev);
-
- CATCH_ALL
- ODSetSOMException(ev, ErrorCode());
-
- // Clean up will occur in the destructor which will be called
- // shortly after we return the error.
- RERAISE;
- ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // Method: InitPartFromStorage
- // Origin: ODPart
- //
- // Description: This method is called when a document/stationery is
- // being opened or when the part is internalized by its
- // containing part. The part should merely read in the
- // saved state/content and initialize itself. The part
- // must not alter its storage unit; otherwise, the "Save"
- // menu item becomes enabled without the user actually
- // having made a change to the document.
- //------------------------------------------------------------------------------
-
- void DrawEditor::InitPartFromStorage( Environment* ev,
- ODStorageUnit* storageUnit,
- ODPart* partWrapper )
- {
- SOM_Trace("DrawEditor","InitPartFromStorage");
-
- TRY
- // To allow editor swapping (translation) at runtime, OpenDoc requires
- // that we pass in a "reference" to ourselves when interacting with the
- // API (ie. WindowState::RegisterWindow(), Dispatcher::RegisterIdle, etc).
- // The "partWrapper" passed to us here and in InitPart is the
- // "reference" OpenDoc is asking us to use.
- fSelf = partWrapper;
-
- // Are we being opened from a read-only draft? If so, we cannot
- // write anything back out to our storage unit.
- fReadOnlyStorage = ( this->GetDraft(ev)->
- GetPermissions(ev) == kODDPReadOnly );
-
- // Call the common initialization code to get set up.
- this->Initialize(ev);
-
- // Read in the state the part was in when it was last Externalized.
- // This allows the part to present the same "environment" the user
- // had the part set up in the last time it was edited.
- this->InternalizeStateInfo(ev, storageUnit);
-
- // Read in the contents for your part editor.
- this->InternalizeContent(ev, storageUnit);
-
- CATCH_ALL
- ODSetSOMException(ev, ErrorCode());
-
- // Clean up will occur in the destructor which will be called
- // shortly after we return the error.
- RERAISE;
- ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // Method: Initialize
- // Origin: DrawEditor
- //
- // Description: This method is called during the internalization of
- // the part from a document. The methods purpose is to
- // initialize all fields of the part and to convert
- // ISO types to tokens for faster comparisons throughout
- // the code.
- //------------------------------------------------------------------------------
-
- void DrawEditor::Initialize( Environment* ev )
- {
- SOM_Trace("DrawEditor","Initialize");
-
- // Profiling
- #ifdef qProfileDrawEditor
- OSErr err = ::ProfilerInit(collectDetailed, ticksTimeBase, 200, 22);
- ::ProfilerSetStatus(kODFalse);
- #endif
-
- // Grab a reference to the Session object. This is merely for
- // convenience.
- ODSession* session = GetODPart()->GetStorageUnit(ev)->GetSession(ev);
-
- // Create a list to keep track of the facets we are being
- // displayed in. Also used for maintenance (i.e., Purging memory).
- fDisplayFrameProxies = new COrderedList;
-
- fShapeList = new COrderedList;
- fPublishLinks = new COrderedList;
- fSubscribeLinks = new COrderedList;
-
- // Create a content object which knows how to internalize and externalize
- fPartContent = new CPartContent(this, fShapeList, fPublishLinks, fSubscribeLinks);
-
- // Create a list to keep track of the embedded frames we have.
- fEmbeddedFrames = new COrderedList;
-
- // Instantiate the current selection
- fSelection = new CSelection(this, kODFalse, kODFalse);
-
- // First check to see if the library's global variables have
- // been initialized (meaning another part instantiation is already
- // running).
-
- if ( gGlobalsUsageCount == 0 )
- {
- // Allocate globals structure
- gGlobals = new DrawEditorGlobals;
-
- // Acces our resource file
- ODSLong savedRefNum;
- savedRefNum = BeginUsingLibraryResources();
-
- // Load our floating window def proc in case the 7.5 def proc
- // is not available ( could check system version here.. ).
- gGlobals->fFloatWindowProc = ::GetResource('WDEF', kFloatWindowDefID);
-
- EndUsingLibraryResources(savedRefNum);
-
-
- // Cache the ISO representation o 'TEXT' so we don't have to call
- // translation every time
- ODTranslation* translation = this->GetSession(ev)->GetTranslation(ev);
- gGlobals->fCurrentTextPartKind = translation->GetISOTypeFromPlatformType(ev,
- 'TEXT', kODPlatformDataType);
-
- // It is required that parts instantiate their menu bars from
- // the base OpenDoc menu bar. This maintains consistency in the
- // default menu items and their placement.
- // Since the object is a copy, we can add and subtract menus and
- // items without affecting other running parts.
- gGlobals->fMenuBar = session->GetWindowState(ev)->CopyBaseMenuBar(ev);
-
- // Load and register our menus
- this->LoadMenus(ev);
-
- // We will be using the following foci (shared resources) in this
- // part. For convenience, we tokenize the values here and store
- // them for equivalence tests in the activation methods.
- gGlobals->fClipboardFocus = session->Tokenize(ev, kODClipboardFocus);
- gGlobals->fSelectionFocus = session->Tokenize(ev, kODSelectionFocus);
- gGlobals->fMenuFocus = session->Tokenize(ev, kODMenuFocus);
- gGlobals->fModalFocus = session->Tokenize(ev, kODModalFocus);
- gGlobals->fKeyFocus = session->Tokenize(ev, kODKeyFocus);
-
- // If we don't acquire the key focus as a part of our focus set
- // then embedded text editors will leave carets lying around.
- // It would also be necessary if nudge were implemented.
- gGlobals->fKeyFocus = session->Tokenize(ev, kODKeyFocus);
-
- // Also for convenience, we tokenize our part's main presentation
- // and the standard view types.
- gGlobals->fMainPresentation = session->Tokenize(ev, kMainPresentation);
- gGlobals->fUndefinedPresentation = session->Tokenize(ev, kODPresDefault);
-
- gGlobals->fFrameView = session->Tokenize(ev, kODViewAsFrame);
- gGlobals->fLargeIconView = session->Tokenize(ev, kODViewAsLargeIcon);
- gGlobals->fSmallIconView = session->Tokenize(ev, kODViewAsSmallIcon);
- gGlobals->fThumbnailView = session->Tokenize(ev, kODViewAsThumbnail);
-
- // Allocate the Color & Tool Palettes
- gGlobals->fColorPalette = new CColorPalette(this);
- gGlobals->fToolPalette = new CToolPalette(this);
-
- // Cache black as it is represented in our color palette
- gGlobals->fBlackColor = new CRGBColor();
- gGlobals->fColorPalette->GetColor(kBlackColor, gGlobals->fBlackColor);
-
- // Lastly, we will package the menu and selection focus
- // so that we can request the "set" at activation time.
- gGlobals->fUIFocusSet = session->GetArbitrator(ev)->CreateFocusSet(ev);
- gGlobals->fUIFocusSet->Add(ev, gGlobals->fMenuFocus);
- gGlobals->fUIFocusSet->Add(ev, gGlobals->fSelectionFocus);
- gGlobals->fUIFocusSet->Add(ev, gGlobals->fKeyFocus);
-
- // Determine what Script/Language the part is localized for.
- // This is important/necessary for creating OpenDoc's text objects.
- GetEditorScriptLanguage(ev, &gGlobals->fEditorsScript, &gGlobals->fEditorsLanguage);
-
- // The first client of the global variables is running.
- gGlobalsUsageCount = 1;
- }
- else
- // If the globals have been initialized, we just bump the refcount of the
- // menu bar. This prevents will prevent it from going away before we are
- // done using it. We also keep a "usage" count so that we can null out the
- // global variables when we are finished using them.
- {
- gGlobalsUsageCount++;
- }
- }
-
-
-
- //------------------------------------------------------------------------------
- // Method: LoadMenus
- // Origin: DrawEditor
- //
- // Description: This method is called the first time an instance
- // of this part is initalized to create DrawEditor
- // specific menus and add them to the menubar.
- //
- // Warning: This method assumes that the global gGlobals->fMenuBar has been initialized.
- //------------------------------------------------------------------------------
-
- void DrawEditor::LoadMenus( Environment* ev )
- {
- SOM_Trace("DrawEditor","LoadMenus");
-
- // Load menu resources and add them to the menubar
- ODSLong ref;
- ref = BeginUsingLibraryResources();
-
- TRY
- gGlobals->fMenuBar->AddMenuLast(ev, kLayoutMenuID, GetMenu(kLayoutMenuID), GetODPart());
- gGlobals->fMenuBar->AddMenuLast(ev, kPalettesMenuID, GetMenu(kPalettesMenuID), GetODPart());
-
- CATCH_ALL
- #ifdef ODDebug
- DebugStr("\p Add of menu failed!");
- #endif
-
- ENDTRY
-
- EndUsingLibraryResources(ref);
-
- // Layout Menu
- gGlobals->fMenuBar->RegisterCommand( ev, kMoveForwardCmd, kLayoutMenuID, kMoveForwardItem );
- gGlobals->fMenuBar->RegisterCommand( ev, kMoveFrontCmd, kLayoutMenuID, kMoveFrontItem );
- gGlobals->fMenuBar->RegisterCommand( ev, kMoveBackwardCmd, kLayoutMenuID, kMoveBackwardItem );
- gGlobals->fMenuBar->RegisterCommand( ev, kMoveBackCmd, kLayoutMenuID, kMoveBackItem );
- // gGlobals->fMenuBar->RegisterCommand(ev, kWrapToParItem, kLayoutMenuID, kWrapToPartCmd);
-
- // Palettes Menu
- gGlobals->fMenuBar->RegisterCommand( ev, kShowHideToolPaletteCmd, kPalettesMenuID, kToolPaletteItem );
- gGlobals->fMenuBar->RegisterCommand( ev, kShowHideColorPaletteCmd, kPalettesMenuID, kColorPaletteItem );
-
- }
-
- //------------------------------------------------------------------------------
- // Method: AdjustMenus
- //
- // Description: This method is called when a kODEvtMouseDown event
- // occurs in the menubar and the part owns the "menu"
- // focus.
- //
- // The part enables the appropriate items for its current
- // state and updates the menu items to reflect this
- // editor.
- //------------------------------------------------------------------------------
-
- void DrawEditor::AdjustMenus( Environment* ev,
- ODFrame* frame )
- {
- SOM_Trace("DrawEditor","AdjustMenus");
-
- // Enable the "View As Window" command always while we are not the root part.
- gGlobals->fMenuBar->EnableCommand(ev, kODCommandViewAsWin, !frame->IsRoot(ev));
-
- // Change the "About" menu item text for our part.
- ::SetMenuItemText( ev, kODCommandAbout, kAboutTextID );
-
- // Change the text for the color palette menu item
- if (gGlobals->fColorPalette->IsShown(ev))
- ::SetMenuItemText( ev, kShowHideColorPaletteCmd, kHideColorPaletteIndex );
- else
- ::SetMenuItemText( ev, kShowHideColorPaletteCmd, kShowColorPaletteIndex );
-
- // Change the text for the tool palette menu item
- if (gGlobals->fToolPalette->IsShown(ev))
- ::SetMenuItemText( ev, kShowHideToolPaletteCmd, kHideToolPaletteIndex );
- else
- ::SetMenuItemText( ev, kShowHideToolPaletteCmd, kShowToolPaletteIndex );
-
-
- // File menu
- gGlobals->fMenuBar->EnableCommand(ev, kODCommandOpen, !fSelection->IsEmpty());
-
- ODBoolean canModify = !this->IsReadOnly();
- ODBoolean canClear = canModify && fSelection->CanMoveSelectedContent();
-
- // Edit menu
- if (fSelection->IsOneLink())
- {
- ::SetMenuItemText( ev, kODCommandGetPartInfo, kLinkInfoIndex );
- gGlobals->fMenuBar->EnableCommand(ev, kODCommandGetPartInfo, kODTrue);
- }
- else
- {
- gGlobals->fMenuBar->EnableCommand(ev, kODCommandGetPartInfo,
- fSelection->IsOneEmbeddedShape(ev)!=kODNULL);
- }
-
- gGlobals->fMenuBar->EnableCommand(ev, kODCommandClear, canClear);
- gGlobals->fMenuBar->EnableCommand(ev, kODCommandSelectAll, fShapeList->Count()>0);
-
- // Clipboard
- ODArbitrator* tArbitrator = this->GetSession(ev)->GetArbitrator(ev);
- ODFrame* clipboardFocusOwner = tArbitrator->AcquireFocusOwner(ev, gGlobals->fClipboardFocus);
- if ( (frame == clipboardFocusOwner) ||
- (tArbitrator->RequestFocus(ev, gGlobals->fClipboardFocus, frame)) )
- {
-
- // This will allow the pasting of foreign content.
- // Pass kODNULL for the kind, to just test for content.
- ODBoolean canPaste = canModify && ValueOnClipboard(ev, kODNULL, this->GetSession(ev));
-
- // enable cut only if we have a selection and the draft is modifiable
- gGlobals->fMenuBar->EnableCommand(ev, kODCommandCut, canClear);
-
- // Can only copy if we have a selection
- gGlobals->fMenuBar->EnableCommand(ev, kODCommandCopy, !fSelection->IsEmpty());
-
- // enable paste only if we support the type available & the drafts modifiable
- gGlobals->fMenuBar->EnableCommand(ev, kODCommandPaste, canPaste);
- gGlobals->fMenuBar->EnableCommand(ev, kODCommandPasteAs, canPaste);
- }
- ODReleaseObject(ev, clipboardFocusOwner);
-
- // It's ok to re-order a link destinations as a whole with respect to the other
- // shapes, but it does not make sense to reorder part's of them. Since currently
- // link updates don't respect order at all, this may be moot.
- gGlobals->fMenuBar->EnableCommand(ev, kMoveForwardCmd, canClear);
- gGlobals->fMenuBar->EnableCommand(ev, kMoveFrontCmd, canClear);
- gGlobals->fMenuBar->EnableCommand(ev, kMoveBackwardCmd, canClear);
-
- }
-
-
- //------------------------------------------------------------------------------
- // Method: Release
- // Origin: ODPart
- //
- // Description: This method is called each time an object releases the
- // part. If the refcount falls to 0, the part should
- // release the GetODPart() part reference.
- //
- // Warning: If the part releases any other object when the refcount falls to
- // zero, it will need to override the Acquire method so
- // that the object can be referenced again if the parts refcount
- // should be incremented before it is deleted.
- //------------------------------------------------------------------------------
-
- void DrawEditor::Release( Environment* ev )
- {
- SOM_Trace("DrawEditor","Release");
-
- ODPart* tPart = this->GetODPart();
-
- if (tPart->GetRefCount(ev) == 0)
- this->GetDraft(ev)->ReleasePart(ev, tPart);
- }
-
- //------------------------------------------------------------------------------
- // Method: ReleaseAll
- // Origin: ODPart
- //
- // Description: This method is called just prior to the part being
- // deleted by the Draft. The part must release all
- // references to all refcounted objects it has stored
- // internally; not doing so, will cause an "invalid ref
- // count" exception/error.
- //------------------------------------------------------------------------------
-
- void DrawEditor::ReleaseAll( Environment* ev )
- {
- SOM_Trace("DrawEditor","ReleaseAll");
-
- TRY
-
- // Profiling
- #ifdef qProfileDrawEditor
- char x[255] = "/pDrawEditorProfile";
- OSErr err = ::ProfilerDump((StringPtr)"\pServo:DrawEditorProfile");
- ::ProfilerTerm();
- #endif
-
- // Check to see if we have any promises on the clipboard
- // if so, resolve them, per recipe.
- ::ResolveClipboardPromises(ev, this->GetSession(ev));
-
- // Release our global floating window proc
- if (gGlobals->fFloatWindowProc)
- ::ReleaseResource(gGlobals->fFloatWindowProc);
-
- // Release our display frames and delete their proxy
- if (fDisplayFrameProxies)
- {
- COrdListIterator fiter(fDisplayFrameProxies);
- for ( CDisplayFrameProxy* frameProxy = (CDisplayFrameProxy*)fiter.First();
- fiter.IsNotComplete();
- frameProxy=(CDisplayFrameProxy*)fiter.Next())
- {
- if (frameProxy->IsFrameInMemory())
- {
- ODFrame* frame = frameProxy->GetFrame(ev);
- ODReleaseObject(ev,frame);
- }
- delete frameProxy;
- }
- }
-
- //
- if ( fDisplayFrameProxies )
- {
- ODDeleteObject(fDisplayFrameProxies);
- fDisplayFrameProxies = kODNULL;
- }
-
-
- if (fPendingPublish && fPendingPublish->CanDelete())
- delete fPendingPublish;
-
- fPendingPublish = NULL;
-
- if (fPendingDragPublish && fPendingDragPublish->CanDelete())
- delete fPendingDragPublish;
-
- fPendingDragPublish = NULL;
-
- // Delete publishers
- if (fPublishLinks)
- {
- CPublishLink* link;
- while ((link = (CPublishLink*)fPublishLinks->RemoveFirst()) != NULL)
- {
- delete link;
- }
- }
-
- // Delete subscribers
- if (fSubscribeLinks)
- {
- CSubscribeLink* link;
- while ((link = (CSubscribeLink*)fSubscribeLinks->RemoveFirst()) != NULL)
- {
- delete link;
- }
- }
-
- // Destroy our content shapes
- if (fShapeList)
- {
- COrdListIterator iter(fShapeList);
- for ( CShape* shape = (CShape*)iter.First();
- iter.IsNotComplete();
- shape = (CShape*)iter.Next() )
- {
- delete shape;
- }
- }
-
-
- // Release the active border shape
- if (fActiveBorderShape)
- {
- ODReleaseObject(ev,fActiveBorderShape);
- }
-
- // If the last part instance using the globals is released,
- // we need to NULL out the globals.
-
- if ( --gGlobalsUsageCount == 0 )
- {
- // Release the menu bar
- ODReleaseObject(ev,gGlobals->fMenuBar);
-
- // the FocusSet is not shared so delet it
- if ( gGlobals->fUIFocusSet )
- {
- ODDeleteObject(gGlobals->fUIFocusSet);
- gGlobals->fUIFocusSet = kODNULL;
- }
-
- // Release the thumbnail (PICT) resource.
- if ( gGlobals->fThumbnail )
- {
- ReleaseResource(gGlobals->fThumbnail);
- gGlobals->fThumbnail = kODNULL;
- }
-
- // Also, getting rid of our palettes is good idea also.
- if (gGlobals->fColorPalette)
- {
- ODDeleteObject(gGlobals->fColorPalette);
- gGlobals->fColorPalette = kODNULL;
- }
- if (gGlobals->fToolPalette)
- {
- ODDeleteObject(gGlobals->fToolPalette);
- gGlobals->fToolPalette = kODNULL;
- }
- }
-
- CATCH_ALL
- // If something goes wrong while we are cleaning up, we must
- // let the Draft know because there may be some refcounted objects
- // which did not get released. Not to mention, possible memory
- // leaks.
- RERAISE;
- ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // Method: Purge
- // Origin: ODPart
- //
- // Description: This method is called when the OpenDoc requires more
- // memory for allocating objects and just before a part
- // is deleted. The part should free up as much memory as
- // it can.
- //
- // The part determines which views are being "used" in
- // its display frames. The resources for the unused view
- // types are then purged.
- //------------------------------------------------------------------------------
-
- ODSize DrawEditor::Purge( Environment* ev,
- ODSize /*size*/ )
- {
- SOM_Trace("DrawEditor","Purge");
-
- // Purge is called during the creation of stationery. However,
- // we have not created our internal display frames list, so
- // trying to iterate over it would be futile.
- if ( !fDisplayFrameProxies ) return 0;
-
- ODSize bytesFreed = 0;
- ODBoolean usingGlobals = kODFalse;
-
- // Iterate over the frames we are displayed through and determine which
- // view types are currently in use.
-
- COrdListIterator fiter(fDisplayFrameProxies);
- for ( CDisplayFrameProxy* frameProxy = (CDisplayFrameProxy*)fiter.First();
- fiter.IsNotComplete();
- frameProxy=(CDisplayFrameProxy*)fiter.Next())
- {
- if (frameProxy->IsFrameInMemory())
- {
- ODFrame* frame = frameProxy->GetFrame(ev);
- ODTypeToken frameView = frame->GetViewType(ev);
-
- if ( frameView == gGlobals->fThumbnailView )
- usingGlobals = kODTrue;
- }
- }
-
- // Based on the usage of the supported view types, free up as much
- // memory as possible.
-
- if ( !usingGlobals && (gGlobals->fThumbnail != kODNULL) )
- {
- bytesFreed += (ODSize) GetHandleSize(gGlobals->fThumbnail);
- ::ODDeletePicture((PicHandle)gGlobals->fThumbnail);
- gGlobals->fThumbnail = kODNULL;
- }
-
- return bytesFreed;
- }
-
- //------------------------------------------------------------------------------
- // Method: InternalizeStateInfo
- // Origin: DrawEditor
- //
- // Description: This method could be used to read in settings
- // information for the part. This would be information
- // related to the workings of the part editor, not the
- // content.
- //
- // Note: The function StorageUnitGetValue simplifies the use of
- // ODByteArrary, which is required by the StorageUnit
- // interface. Look in StorUtil.h/cpp for an example of
- // using the ODByteArray struct.
- //------------------------------------------------------------------------------
-
- void DrawEditor::InternalizeStateInfo( Environment* ev,
- ODStorageUnit* storageUnit )
- {
- SOM_Trace("DrawEditor","InternalizeStateInfo");
-
- // Internalize the part's display frame proxy list.
-
- ODULong size;
-
- if ( storageUnit->Exists(ev, kODPropDisplayFrames, kODWeakStorageUnitRefs, 0) )
- {
- storageUnit->Focus(ev, kODPropDisplayFrames, kODPosUndefined,
- kODWeakStorageUnitRefs, 0, kODPosUndefined);
-
- // Read test value
- ODUShort testValue = 0;
- StorageUnitGetValue(storageUnit, ev, sizeof(ODUShort), &testValue);
-
- size = storageUnit->GetSize(ev);
- storageUnit->SetOffset(ev, 0);
-
- for ( ODULong offset = 0; offset < size; offset += sizeof(ODStorageUnitRef) )
- {
- CDisplayFrameProxy* tProxy = kODNULL;
- ODVolatile(tProxy);
- TRY
- CDisplayFrameProxy* tProxy = new CDisplayFrameProxy();
- tProxy->InitializeDisplayFrameProxy(ev, this);
-
- tProxy->Read(ev, storageUnit, kODNULL);
- fDisplayFrameProxies->AddLast(tProxy);
- CATCH_ALL
- if (tProxy)
- {
- delete tProxy;
- }
- ENDTRY
- }
- }
- }
-
- //------------------------------------------------------------------------------
- // Method: InternalizeContent
- // Origin: DrawEditor
- //
- // Description: This method is called during interalization of the
- // part. Document state info, content of part, as well as any link info
- // is read in. The work is all done by the CDrawContent object.
- //------------------------------------------------------------------------------
-
- void DrawEditor::InternalizeContent( Environment* ev,
- ODStorageUnit* storageUnit )
- {
- SOM_Trace("DrawEditor","InternalizeContent");
-
- // focus to our content property.
- TRY
- if ( storageUnit->Exists(ev, kODPropContents, kDrawEditorKind, 0) )
- {
- storageUnit->Focus(ev, kODPropContents, kODPosUndefined,
- kDrawEditorKind, 0, kODPosUndefined);
-
- fPartContent->Internalize(ev, storageUnit, kODNULL);
- }
- CATCH_ALL
- ODSetSOMException(ev, ErrorCode());
- ENDTRY
-
-
- }
-
- //------------------------------------------------------------------------------
- // Method: ClonePartInfo
- // Origin: ODPart
- //
- // Description: When a frame is being cloned by the Draft, it will ask the owner
- // (part) to clone its info annotation on the frame.
- //
- // The part uses a C++ helper class to encapsulate the information
- // we store with each frame, so we let it clone itself to the
- // storage unit view.
- //------------------------------------------------------------------------------
-
- void DrawEditor::ClonePartInfo( Environment* ev,
- ODDraftKey key,
- ODInfoType partInfo,
- ODStorageUnitView* storageUnitView,
- ODFrame* scopeFrame )
- {
- SOM_Trace("ClonePartInfo","ClonePartInfo");
-
- // Tell our frame info class to write itself out into the pre-
- // focused storage unit.
- ((CFrameInfo*) partInfo)->CloneInto(ev, key, storageUnitView, scopeFrame);
- }
-
-
- //------------------------------------------------------------------------------
- // Method: CloneInto
- // Origin: ODPart
- //
- // Description: This method is called during cloning, typically
- // inside of Data Interchange operations. The part should
- // write out the current state and contents.
- //------------------------------------------------------------------------------
-
- void DrawEditor::CloneInto( Environment* ev,
- ODDraftKey key,
- ODStorageUnit* destinationSU,
- ODFrame* scopeFrame )
- {
- SOM_Trace("DrawEditor","CloneInto");
-
- // We must first verify that we've never written to this storage unit.
- // If we have, we should do nothing, otherwise we need to write out
- // the current state of the part content.
-
- if ( destinationSU->Exists(ev, kODPropContents, kDrawEditorKind, 0) == kODFalse )
- {
-
- // This is where, we should check for the existence of the kODPropContentFrame property
- // and write a promise if it's there. When doing so, we will need to read any kODPropCloneKind's kODCloneKind value
- // and use that in our cloneKind record. Otherwise the promise, when fulfilled may call BeginClone with the wrong
- // cloneKind (ie one different from the containing part which called BeginClone before cloning this as a single
- // embedded frame.
-
- // based
- // Add the properties we need to successfully externalize
- // ourselves into the destination storage unit.
- this->CheckAndAddProperties(ev, destinationSU);
-
- // Assemble the bits of info necessary for the clone operation.
- // These are the: key from the clone begun by OD, the source draft,
- // the scope frame, and the clone kind.
- CCloneInfo info(key, this->GetDraft(ev), scopeFrame, kODCloneCopy);
-
- // Write out the part's state information.
- this->ExternalizeStateInfo(ev, destinationSU, &info);
-
- // Write out the part's content.
- this->ExternalizeContent(ev, destinationSU, &info);
- }
- }
-
- //------------------------------------------------------------------------------
- // Method: Externalize
- // Origin: ODPart
- //
- // Description: Write out our persistent state if changes have
- // occurred and if our storage is writeable. The part
- // must call its parent class behavior because one or
- // more of our parent classes contains implementation.
- //------------------------------------------------------------------------------
-
- void DrawEditor::Externalize( Environment* ev )
- {
- SOM_Trace("DrawEditor","Externalize");
-
- if ( fDirty && !IsReadOnly())
- {
- TRY
-
- // Get our storage unit.
- ODStorageUnit* storageUnit = this->GetODPart()->GetStorageUnit(ev);
-
- // Verify that the storage unit has the appropriate properties
- // and values to allow us to run. If not, add them.
- this->CheckAndAddProperties(ev, storageUnit);
-
- // Verify that there are no "bogus" values in the Content
- // property.
- this->CleanseContentProperty(ev, storageUnit);
-
- // Write out the part's state information.
- this->ExternalizeStateInfo(ev, storageUnit, kODNULL);
-
- // Write out the part's content.
- this->ExternalizeContent(ev, storageUnit, kODNULL);
-
- CATCH_ALL
- // Alert the user of the problem.
- this->DoDialogBox(ev, kODNULL, kErrorBoxID, kErrExternalizeFailed);
- // Change the exception value, so the DocShell doesn't display an
- // error dialog.
- SetErrorCode(kODErrAlreadyNotified);
- // Alert the caller.
- RERAISE;
- ENDTRY
-
- // Flag our part as no longer being dirty.
- fDirty = kODFalse;
- }
- }
-
- //------------------------------------------------------------------------------
- // Method: ExternalizeStateInfo
- // Origin: DrawEditor
- // Description: This method is called during externalization pr cloning of the
- // part. The current "state" of the editor should be
- // written out. This "state" information may be lost
- // during Data Interchange operations, so the part needs
- // to recover gracefully if information is missing or
- // incomplete.
- //
- // Note: The function StorageUnitSetValue is a macro which
- // simplifies the use of ODByteArrary, which is required
- // the StorageUnit interface. Look in StorUtil.h/cpp for
- // an example of using the ODByteArray struct.
- //------------------------------------------------------------------------------
-
- void DrawEditor::ExternalizeStateInfo( Environment* ev,
- ODStorageUnit* storageUnit,
- CCloneInfo* info)
- {
- SOM_Trace("DrawEditor","ExternalizeStateInfo");
-
- // Externalize the part's display frame list.
-
- storageUnit->Focus(ev, kODPropDisplayFrames, kODPosUndefined,
- kODWeakStorageUnitRefs, 0, kODPosUndefined);
-
- // Persistent object references are stored in a side table, rather than
- // in the property/value stream. Thus, deleting the contents of a value
- // will not "delete" the references previously written to that value. To
- // completely "delete" all references written to the value, we must
- // remove the value and add it back.
- storageUnit->Remove(ev);
- storageUnit->AddValue(ev, kODWeakStorageUnitRefs);
-
- COrdListIterator fiter2(fDisplayFrameProxies);
- for ( CDisplayFrameProxy* frameProxy = (CDisplayFrameProxy*)fiter2.First();
- fiter2.IsNotComplete();
- frameProxy = (CDisplayFrameProxy*)fiter2.Next())
- {
- TRY
- // Only write frame proxies if they are the main presentation
- // since our palettes are not persistent. This test does not
- // take into account the possiblity of a proxy being added
- // by ID that should be saved. Currently DrawEditor doesn't allow
- // that to happen.
- if (frameProxy->IsFrameInMemory())
- {
- ODFrame* tFrame = frameProxy->GetFrame(ev);
- if (tFrame->GetPresentation(ev)==gGlobals->fMainPresentation)
- {
- frameProxy->Write(ev, storageUnit, info);
- }
- }
- CATCH_ALL
- // Consume the exception
- #ifdef ODDebug
- DebugStr("\pFailure externalizing state info.");
- #endif
- ENDTRY
- }
- }
-
- //------------------------------------------------------------------------------
- // Method: ExternalizeContent
- // Origin: DrawEditor
- //
- // Description: This method is called during exteralization of the
- // part. The content of the part should be written out.
- //
- // Note: This method adds an additional parameter unlike other parts derived
- // from DrawEditor. The cloneInfo parameter is used to communicate clone info
- // passed into the CloneInto method so that the editor may clone embedded its
- // embedded frames to the given storage.
- //------------------------------------------------------------------------------
-
- void DrawEditor::ExternalizeContent( Environment* ev,
- ODStorageUnit* storageUnit,
- CCloneInfo* cloneInfo )
- {
- SOM_Trace("DrawEditor","ExternalizeContent");
-
- TRY
- // focus to our content property.
- if ( storageUnit->Exists(ev, kODPropContents, kDrawEditorKind, 0) )
- {
- storageUnit->Focus(ev, kODPropContents, kODPosUndefined,
- kDrawEditorKind, 0, kODPosUndefined);
-
- fPartContent->Externalize(ev, storageUnit, cloneInfo);
- }
-
- CATCH_ALL
- ODSetSOMException(ev, ErrorCode());
- ENDTRY
-
-
- }
-
- //------------------------------------------------------------------------------
- // Method: FulfillPromise
- // Origin: DrawEditor
- //
- // Description: This method is called by OpenDoc when a promise of data ( that
- // we made ) needs to be resolved. The storage unit we get passed should be
- // focused to a proeprty and value containing our original byte array that we
- // promised earlier. We need to read that byte array and use it to write the
- // actual data that was promisedf into that SAME property and value.
- //------------------------------------------------------------------------------
-
- void DrawEditor::FulfillPromise(Environment* ev, ODStorageUnitView* promiseSUView)
- {
- CPromise* promise = kODNULL;
- TRY
- StorageUnitViewGetValue(promiseSUView, ev, sizeof(CPromise*), &promise);
- THROW_IF_NULL(promise);
-
- // Reset the storage unit view so the value we just read will get overwritten.
- promiseSUView->SetOffset(ev, 0);
-
- // We assume that the promise that was returned by the get value call wwas good.
- promise->FulfillPromise(ev, promiseSUView);
-
- CATCH_ALL
- ODSetSOMException(ev, ErrorCode());
- ENDTRY
-
- // The promise could be null if we've thrown above.
- if (promise)
- {
- if (promise->OKToDelete())
- {
- delete promise;
- }
- }
- }
-
-
- //------------------------------------------------------------------------------
- // Method: CleanseContentProperty
- // Origin: DrawEditor
- //
- // Description: This method is called during exteralization of the
- // part. The part should remove any value in the content property
- // that it cannot "accurately" write to.
- //------------------------------------------------------------------------------
-
- void DrawEditor::CleanseContentProperty( Environment* ev,
- ODStorageUnit* storageUnit )
- {
- SOM_Trace("DrawEditor","CleanseContentProperty");
-
- ODULong numValues;
- ODULong index;
-
- storageUnit->Focus(ev, kODPropContents, kODPosUndefined,
- kODNULL, 0, kODPosAll);
-
- numValues = storageUnit->CountValues(ev);
-
- for (index = numValues; index >= 1; index--)
- {
- // Index from 1 to n through the values.
- storageUnit->Focus(ev, kODPropContents, kODPosUndefined,
- kODNULL, index, kODPosUndefined);
-
- // Get the ISO type name for the value. The temp object
- // will automatically delete the returned value when this
- // scope is exited.
- TempODValueType value = storageUnit->GetType(ev);
-
- // If the value type is not one we support, remove it.
- if ( ODISOStrCompare(value, kDrawEditorKind) != 0 )
- storageUnit->Remove(ev);
- }
- }
-
- //------------------------------------------------------------------------------
- // Method: CheckAndAddProperties
- // Origin: DrawEditor
- //
- // Description: This method is called during the creation of
- // stationery, to prepare a storage unit, and during
- // externalization, to verify that all the properties we
- // need are present.
- //
- // The part adds the default content property, a
- // preferred editor property (to aid in part binding),
- // and a default name for the part.
- //
- // Note: The function StorageUnitSetValue is a macro which
- // simplifies the use of ODByteArrary, which is required
- // the StorageUnit interface. Look in StorUtil.h/cpp for
- // an example of using the ODByteArray struct.
- //------------------------------------------------------------------------------
-
- void DrawEditor::CheckAndAddProperties( Environment* ev,
- ODStorageUnit* storageUnit )
- {
- SOM_Trace("DrawEditor","CheckAndAddProperties");
-
- // Create our content property and preferred content property kind.
-
- if ( !storageUnit->Exists(ev, kODPropContents, kODNULL, 0) )
- storageUnit->AddProperty(ev, kODPropContents);
- if ( !storageUnit->Exists(ev, kODPropContents, kDrawEditorKind, 0) )
- {
- storageUnit->Focus(ev, kODPropContents, kODPosUndefined, kODNULL, 0, kODPosAll);
- storageUnit->AddValue(ev, kDrawEditorKind);
- }
-
- // Since we are setting up the preferred kind property, we just write
- // out our default "kind" for the editor. We can write out the user
- // chosen kind in the ExternalizeStateInfo method.
-
- if ( !storageUnit->Exists(ev, kODPropPreferredKind, kODISOStr, 0) )
- {
- TRY
- ODSetISOStrProp(ev, storageUnit, kODPropPreferredKind, kODISOStr, kDrawEditorKind);
- CATCH_ALL
- // Remove the property and value if something went wrong.
- ODSURemoveProperty(ev, storageUnit, kODPropPreferredKind);
- ENDTRY
- }
-
- // Add our display frame list.
-
- if ( !storageUnit->Exists(ev, kODPropDisplayFrames, kODNULL, 0) )
- storageUnit->AddProperty(ev, kODPropDisplayFrames);
- if ( !storageUnit->Exists(ev, kODPropDisplayFrames, kODWeakStorageUnitRefs, 0) )
- {
- storageUnit->Focus(ev, kODPropDisplayFrames, kODPosUndefined, kODNULL, 0, kODPosAll);
- storageUnit->AddValue(ev, kODWeakStorageUnitRefs);
- }
- }
-
- //------------------------------------------------------------------------------
- // Method: SetDirty
- // Origin: DrawEditor
- //
- // Description: This method is called by the part when the content or
- // state of the part has been modified by the user and
- // the "Save" menu item should be enabled.
- //------------------------------------------------------------------------------
-
- void DrawEditor::SetDirty( Environment* ev )
- {
- SOM_Trace("DrawEditor","SetDirty");
-
- // There is no need to repeatedly tell the draft we have changed;
- // once is sufficient.
- if ( !fDirty && !fReadOnlyStorage )
- {
- fDirty = kODTrue;
- this->GetDraft(ev)->SetChangedFromPrev(ev);
- }
- }
-
-
- //------------------------------------------------------------------------------
- // Method: ExternalizeKinds
- // Origin: ODPart
- //
- // Description: This method is called when the user wants to save the document
- // with multiple representations of the data. This is especially
- // useful for increasing the portability of documents
- // cross-platform.
- //
- // A part should verify each kind is valid, that it exists in
- // the content property in the correct order, and write the data.
- //------------------------------------------------------------------------------
-
- void DrawEditor::ExternalizeKinds(Environment* ev, ODTypeList* kindset)
- {
- if ( !fReadOnlyStorage )
- {
- ODBoolean preferredKindWritten = kODFalse;
-
- // Get our storage unit.
- ODStorageUnit* storageUnit = fSelf->GetStorageUnit(ev);
-
- // Verify that the storage unit has the appropriate properties
- // and values to allow us to run. If not, add them.
- this->CheckAndAddProperties(ev, storageUnit);
-
- // Verify that there are no "bogus" values in the Content
- // property.
- this->CleanseContentProperty(ev, storageUnit);
-
- // Iterate over the kindset and write out the content types
- // that we support.
- TempODTypeListIterator tliter(ev, kindset);
- for ( ODType kind = tliter.First(); tliter.IsNotComplete();
- kind = tliter.Next() )
- {
- // Check to see if this is a kind we support. If so, write it.
- if ( ODISOStrCompare(kind, kDrawEditorKind) == 0 )
- {
- // Write out the part's content.
- this->ExternalizeContent(ev, storageUnit, kODNULL);
- // This is our preferrend kind so we don't need to write it again.
- // Part editors with more than one kind need to test each kind
- // against the preferred kind to make sure it's been written.
- preferredKindWritten = kODTrue;
- }
- }
-
- // Write out the part's state information.
- this->ExternalizeStateInfo(ev, storageUnit, kODNULL);
-
- // Even if the kind set contains no types we support, we must at least
- // write out our current "preferred" kind.
- if ( preferredKindWritten == kODFalse )
- {
- // Write out the part's preferred content kind, which, for DrawEditor,
- // is the only kind.
- this->ExternalizeContent(ev, storageUnit, kODNULL);
- }
- }
- }
-
- //------------------------------------------------------------------------------
- // Method: ChangeKind
- // Origin: ODPart
- //
- // Description: This method is called when the changes the part's primary kind
- // and/or when the part editor is switched via the Info dialog.
- //
- // The editor should record the new "preferred" kind and change the
- // UI, if necessary, to allow editing of that kind. Don't write the
- // properties/values/data until the Externalize is called.
- //------------------------------------------------------------------------------
-
- void DrawEditor::ChangeKind(Environment* ev, ODType kind)
- {
- // DrawEditor only has one kind, but we need to make sure the "Preferred Kind"
- // property has the correct value.
- if ( ODISOStrCompare(kind, kDrawEditorKind) == 0 )
- {
- // Get our storage unit.
- ODStorageUnit* storageUnit = fSelf->GetStorageUnit(ev);
-
- TRY
- // Write out the users preferred kind.
- ODSetISOStrProp(ev, storageUnit, kODPropPreferredKind, kODISOStr, kDrawEditorKind);
-
- // Changing our kind dirties our content.
- this->SetDirty(ev);
-
- // Immediately externalize ourselves in the "new" format.
- this->Externalize(ev);
- CATCH_ALL
- // Remove the property and value if something went wrong.
- ODSURemoveProperty(ev, storageUnit, kODPropPreferredKind);
- ENDTRY
- }
- else
- THROW(kODErrInvalidValueType);
- }
-
-
- //------------------------------------------------------------------------------
- // Method: ReadPartInfo
- // Origin: ODPart
- //
- // Description: When a frame is being internalized by the Draft, it
- // will ask the owner (part) to read in its info
- // annotation on the frame.
- //
- // The part info class knows how to internalize itself
- // from a storage unit view, so we just call
- // CFrameInfo::InitFromStorage.
- //------------------------------------------------------------------------------
-
- ODInfoType DrawEditor::ReadPartInfo( Environment* ev,
- ODFrame* frame,
- ODStorageUnitView* storageUnitView )
- {
- SOM_Trace("DrawEditor","ReadPartInfo");
-
- CFrameInfo* frameInfo = kODNULL;
-
- TRY
- frameInfo = new CFrameInfo;
- frameInfo->InitFromStorage(ev, storageUnitView);
-
- // Hook the runtime display frame synchonization mechanism back up.
- if ( frameInfo->HasSourceFrame() )
- {
- CFrameInfo* sourceFrameInfo =
- (CFrameInfo*) frameInfo->GetSourceFrame()->GetPartInfo(ev);
-
- sourceFrameInfo->AttachFrame(ev, frame);
- }
-
- CATCH_ALL
- ENDTRY
-
- return (ODInfoType)frameInfo;
- }
-
- //------------------------------------------------------------------------------
- // Method: WritePartInfo
- // Origin: ODPart
- //
- // Description: When a frame is being externalized by the Draft, it
- // will ask the owner (part) to write out its info
- // annotation on the frame.
- //
- // The part info class knows how to externalize itself
- // to a storage unit view, so we just call Externalize.
- //------------------------------------------------------------------------------
-
- void DrawEditor::WritePartInfo( Environment* ev,
- ODInfoType partInfo,
- ODStorageUnitView* storageUnitView )
- {
- SOM_Trace("DrawEditor","WritePartInfo");
-
- // Tell our frame info class to write itself out into the pre-
- // focused storage unit.
- ((CFrameInfo*) partInfo)->Externalize(ev, storageUnitView);
- }
-
- //------------------------------------------------------------------------------
- // Method: DisplayFrameAdded
- // Origin: ODPart
- //
- // Description: This method is called in response to a frame being
- // created for our part.
- //
- // The part records the existence of a new display frame
- // in its internal display frame list, as well as,
- // verify that the frame is "set up" correctly (i.e.,
- // valid viewType). The part also creates and stores its
- // "frame info" class in the new frame.
- //------------------------------------------------------------------------------
-
- void DrawEditor::DisplayFrameAdded( Environment* ev,
- ODFrame* frame )
- {
- SOM_Trace("DrawEditor","DisplayFrameAdded");
-
- ODBoolean isMainPresentation = frame->GetPresentation(ev)==gGlobals->fMainPresentation;
-
- // If we are being embedded into another part, the presentation field
- // will be NULL, so we need to set it something meaningful.
- // The view field may also be null, if so, we prefer to be displayed
- // in a frame view.
-
- // We shouldn't be given a frame with an foreign presentation
- // If we do get one, set it to our main presentation.
- ODTypeToken tPresentation = frame->GetPresentation(ev);
- if ( tPresentation != gGlobals->fMainPresentation &&
- tPresentation != gGlobals->fColorPalette->GetPresentation() &&
- tPresentation != gGlobals->fToolPalette->GetPresentation() )
- {
- frame->SetPresentation(ev, gGlobals->fMainPresentation);
- isMainPresentation = kODTrue;
- }
-
-
- // Only frame with gGlobals->fMainPresentation are droppable.
- if (isMainPresentation)
- {
- frame->SetDroppable(ev, kODTrue);
-
- // Create frame proxies for any shapes already added when this
- // frame was added
- COrdListIterator iter(fShapeList);
- if (fShapeList)
- for ( CShape* shape = (CShape*)iter.First();
- iter.IsNotComplete();
- shape = (CShape*)iter.Next() )
- {
- shape->DisplayFrameAdded(ev, frame);
- }
- }
-
-
- // If there is no view type then default it to gGlobals->fFrameView
- if ( frame->GetViewType(ev) == kODNullTypeToken )
- frame->SetViewType(ev, gGlobals->fFrameView);
-
- // Hang our "state" info off of the new display frame. We use
- // the CFrameInfo object for activation, updating, and window
- // maintenance.
-
- CFrameInfo* frameInfo = new CFrameInfo;
- frame->SetPartInfo(ev, (ODInfoType)frameInfo);
-
- // Create a proxy for this frame and add it to our list
- CDisplayFrameProxy* tProxy = new CDisplayFrameProxy();
- tProxy->InitializeDisplayFrameProxy(ev, this, kODNULLID, frame);
- fDisplayFrameProxies->AddLast(tProxy);
-
- // Since we maintain a persistent list of weak references to our
- // persistent display frames, having one added to the part dirties it.
- if (isMainPresentation)
- this->SetDirty(ev);
- }
-
-
- //------------------------------------------------------------------------------
- // Method: DisplayFrameConnected
- // Origin: ODPart
- //
- // Description: This method is called when one of our display frames,
- // previously written out, is internalized. This method
- // is called instead of DisplayFrameAdded because a "new"
- // frame is not being created; an existing one is being
- // reconstituted.
- //------------------------------------------------------------------------------
-
- void DrawEditor::DisplayFrameConnected( Environment* ev,
- ODFrame* frame )
- {
- SOM_Trace("DrawEditor","DisplayFrameConnected");
-
- ODBoolean isMainPresentation = frame->GetPresentation(ev)==gGlobals->fMainPresentation;
-
- // We shouldn't be given a frame with an foreign presentation
- // If we do get one, set it to our main presentation.
- ODTypeToken tPresentation = frame->GetPresentation(ev);
- if ( tPresentation != gGlobals->fMainPresentation &&
- tPresentation != gGlobals->fColorPalette->GetPresentation() &&
- tPresentation != gGlobals->fToolPalette->GetPresentation() )
- {
- frame->SetPresentation(ev, gGlobals->fMainPresentation);
- isMainPresentation = kODTrue;
- }
-
- if ( frame->IsRoot(ev) )
- {
- // If the frame being added is a root frame, we know that a window
- // is associated with this frame. Notify ourselves that we need to
- // clean it up when the frame goes away.
- CFrameInfo* frameInfo = (CFrameInfo*) frame->GetPartInfo(ev);
- frameInfo->SetShouldDisposeWindow(kODTrue);
-
- // In addition, we need to verify that the frame is in "frame" view.
- // If the user dragged an icon from a document to Finder and then
- // opens the resultant document, the view would be "icon". However
- // displaying a icon is useless, so we need to change the view to
- // frame.
- if ( frame->GetViewType(ev) != gGlobals->fFrameView )
- frame->SetViewType(ev, gGlobals->fFrameView);
- }
-
- if (isMainPresentation)
- {
- // Ensure that embedded content is re-attached to saved frames correctly.
- COrdListIterator iter(fShapeList);
- if (fShapeList)
- for ( CShape* shape = (CShape*)iter.First();
- iter.IsNotComplete();
- shape = (CShape*)iter.Next() )
- {
- shape->DisplayFrameConnected(ev, frame);
- }
- }
-
- // Only frame with gGlobals->fMainPresentation are droppable.
- if (frame->GetPresentation(ev)==gGlobals->fMainPresentation)
- frame->SetDroppable(ev, kODTrue);
-
- // Iterate over our display collection to match the frame with
- // an existing proxy with the correct frame ID. If we find it,
- // replace the ID with the actual frame. If we don't find it,
- // signal an error.
- ODBoolean found = kODFalse;
- COrdListIterator fiter(fDisplayFrameProxies);
- for ( CDisplayFrameProxy* proxy = (CDisplayFrameProxy*) fiter.First();
- fiter.IsNotComplete(); proxy = (CDisplayFrameProxy*) fiter.Next() )
- {
- if ( proxy->GetFrameID() == frame->GetID(ev) )
- {
- // Set the proxy as internalized, if it is not already.
- if (!proxy->IsFrameInMemory())
- proxy->SetFrame(frame);
-
- found = kODTrue;
- }
- }
-
- // If we didn't find a proxy, then create one.
- if ( !found )
- {
- CDisplayFrameProxy* tProxy = new CDisplayFrameProxy();
- tProxy->InitializeDisplayFrameProxy(ev, this, kODNULLID, frame);
- fDisplayFrameProxies->AddLast(tProxy);
-
- // Since we maintain a persistent list of weak references to our
- // persistent display frames, having one added to the part dirties it.
- if (isMainPresentation)
- this->SetDirty(ev);
- }
-
- // We've deferred registering our internalized links until now, so that
- // any updates that are precipitated can be added to the selection and redrawn.
-
- COrdListIterator sLinkIte(fSubscribeLinks);
- for (CSubscribeLink* slink = (CSubscribeLink *)sLinkIte.First(); sLinkIte.IsNotComplete(); slink = (CSubscribeLink *)sLinkIte.Next())
- {
- slink->Register(ev);
- }
- }
-
- //------------------------------------------------------------------------------
- // Method: CleanupDisplayFrame
- // Origin: DrawEditor
- //
- // Description: This method is called when a frame has been closed or removed.
- // The method cleans up the references and state information stored
- // in the CFrameInfo class.
- //------------------------------------------------------------------------------
-
- void DrawEditor::CleanupDisplayFrame( Environment* ev,
- ODFrame* frame,
- ODBoolean frameRemoved )
- {
- SOM_Trace("DrawEditor","CleanupDisplayFrame");
-
- ODError error = noErr;
- CFrameInfo* frameInfo = (CFrameInfo*) frame->GetPartInfo(ev);
-
- TRY
- // If we are the root of a child window, we need to notify
- // our source frame that we are going away.
- if ( frameInfo->HasSourceFrame() )
- {
- ODFrame* sourceFrame = frameInfo->GetSourceFrame();
- CFrameInfo* sourceFrameInfo = (CFrameInfo*) sourceFrame->GetPartInfo(ev);
-
- if ( frameRemoved )
- {
- // Invalidate the source frame. We do this because the
- // source frame may have a unique display when it has
- // been opened into a part window. This forces the
- // frame to redraw "not opened".
- sourceFrame->Invalidate(ev, kODNULL, kODNULL);
- }
-
- // Release our reference to the source frame.
- frameInfo->ReleaseSourceFrame(ev);
-
- // Detach ourself from the source frame.
- sourceFrameInfo->DetachFrame(ev);
-
- // If the frame is the root, it is a part window going away
- // and we need to notify our source frame that it no longer
- // has a part window.
- if ( frame->IsRoot(ev) )
- sourceFrameInfo->SetPartWindow(kODNULL);
- }
- CATCH_ALL
- error = ErrorCode();
- ENDTRY
-
- TRY
- // If the frame was removed from the document, we need to remove
- // any child window displaying that frame.
- if ( frameRemoved )
- {
- // If we have a child window, we need to close it.
- if ( frameInfo->HasPartWindow() )
- {
- ODWindow* window = frameInfo->GetPartWindow();
- frameInfo->SetPartWindow(kODNULL);
- window->CloseAndRemove(ev);
- }
- }
- CATCH_ALL
- error = ErrorCode();
- ENDTRY
-
- TRY
- // If we have attached frames, we need to notify them that we
- // are going away.
-
- if ( frameInfo->HasAttachedFrame() )
- {
- CFrameInfo* attachedFrameInfo;
- ODFrame* attachedFrame = frameInfo->GetAttachedFrame();
-
- attachedFrameInfo = (CFrameInfo*) attachedFrame->GetPartInfo(ev);
-
- // Tell the attached frame that it's source is going away.
- attachedFrameInfo->ReleaseSourceFrame(ev);
-
- // Remove the attached frame from our state info.
- frameInfo->DetachFrame(ev);
- }
- CATCH_ALL
- error = ErrorCode();
- ENDTRY
-
- // If anything went wrong, signal an error.
- THROW_IF_ERROR(error);
- }
-
- //------------------------------------------------------------------------------
- // Method: DisplayFrameRemoved
- // Origin: ODPart
- //
- // Description: This method is called in response to a frame being
- // removed from our part.
- //
- // The part removes the frame from its internal display
- // frame list and reliquishes any foci that it still
- // owned. Lastly, if the frame has a source frame
- // (it was the root frame of a part window), we will
- // record the part window bounds so that any subsequent
- // part windows opened on the source frame will appear
- // in the same location.
- //------------------------------------------------------------------------------
-
- void DrawEditor::DisplayFrameRemoved( Environment* ev,
- ODFrame* frame )
- {
- SOM_Trace("DrawEditor","DisplayFrameRemoved");
-
- ODBoolean isMainPresentation = frame->GetPresentation(ev)==gGlobals->fMainPresentation;
-
- TRY
- CFrameInfo* frameInfo = (CFrameInfo*) frame->GetPartInfo(ev);
-
- // Make sure the frame going away does not own any foci. Forgetting
- // to do this, will cause a "refcounting" error when the frame
- // is deleted by the draft.
- this->RelinquishAllFoci(ev, frame);
-
- // Notify any embedded content of frame being removed, if the frame
- // is in the main presentation
- if (frame->GetPresentation(ev)==gGlobals->fMainPresentation)
- {
- COrdListIterator iter(fShapeList);
- if (fShapeList)
- for ( CShape* shape = (CShape*)iter.First();
- iter.IsNotComplete();
- shape = (CShape*)iter.Next() )
- {
- shape->DisplayFrameRemoved(ev, frame);
- }
- }
- else
- {
- // Check and see if the frame being removed belonged
- // to one of our palettes. If so, then the window has
- // also closed. We should notify the palette.
- ODTypeToken presentation = frame->GetPresentation(ev);
- if (gGlobals->fColorPalette->GetPresentation() == presentation)
- gGlobals->fColorPalette->ClosePalette(ev);
- else
- if (gGlobals->fToolPalette->GetPresentation() == presentation)
- gGlobals->fToolPalette->ClosePalette(ev);
- }
-
- // Clean up the display frame.
- this->CleanupDisplayFrame(ev, frame, kFrameClosed);
- // Clean up any associated window.
- this->CleanupWindow(ev, frame);
- // Dispose of the frame's runtime state info.
- frame->SetPartInfo(ev, (ODInfoType) kODNULL);
- ODDeleteObject(frameInfo);
-
- // Locate the proxy, and remove it
- COrdListIterator fiter(fDisplayFrameProxies);
- for ( CDisplayFrameProxy* frameProxy = (CDisplayFrameProxy*)fiter.First();
- fiter.IsNotComplete();
- frameProxy = (CDisplayFrameProxy*)fiter.Next())
- {
- // shouldn't get called to remove a frame that has
- // not yet been internalized
- if (frameProxy->IsFrameInMemory())
- {
- if ( ODObjectsAreEqual(ev, frame,frameProxy->GetFrame(ev)) )
- {
- fiter.RemoveCurrent();
- delete frameProxy;
- }
- }
- }
-
- // Since we maintain a persistent list of weak references to our
- // persistent display frames, having one removed from the part dirties it.
- if (isMainPresentation)
- this->SetDirty(ev);
-
- CATCH_ALL
- this->DoDialogBox(ev, frame, kErrorBoxID, kErrRemoveFrame);
-
- // Alert the caller.
- RERAISE;
- ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // Method: DisplayFrameClosed
- // Origin: ODPart
- //
- // Description: This method is called in response to a frame being
- // closed (not removed).
- //
- // For a part as simple as this, we do not distinguish
- // between a frame being closed or removed. As such, we
- // just call DisplayFrameRemoved.
- //------------------------------------------------------------------------------
-
- void DrawEditor::DisplayFrameClosed( Environment* ev,
- ODFrame* frame )
- {
- SOM_Trace("DrawEditor","DisplayFrameClosed");
-
- TRY
- CFrameInfo* frameInfo = (CFrameInfo*) frame->GetPartInfo(ev);
-
- // Make sure the frame going away does not own any foci. Forgetting
- // to do this, will cause a "refcounting" error when the frame
- // is deleted by the draft.
- this->RelinquishAllFoci(ev, frame);
-
- // Clean up the display frame.
- this->CleanupDisplayFrame(ev, frame, kFrameClosed);
- // Clean up any associated window.
- this->CleanupWindow(ev, frame);
- // Dispose of the frame's runtime state info.
- frame->SetPartInfo(ev, (ODInfoType) kODNULL);
- ODDeleteObject(frameInfo);
-
-
- // Notify any embedded content of frame being removed, if the frame
- // is in the main presentation
- if (frame->GetPresentation(ev)==gGlobals->fMainPresentation)
- {
- COrdListIterator iter(fShapeList);
- if (fShapeList)
- for ( CShape* shape = (CShape*)iter.First();
- iter.IsNotComplete();
- shape = (CShape*)iter.Next() )
- {
- shape->DisplayFrameClosed(ev, frame);
- }
- }
- else
- {
- // Check and see if the frame being removed belonged
- // to one of our palettes. If so, then the window has
- // also closed. We should notify the palette.
- ODTypeToken presentation = frame->GetPresentation(ev);
- if (gGlobals->fColorPalette->GetPresentation() == presentation)
- gGlobals->fColorPalette->ClosePalette(ev);
- else
- if (gGlobals->fToolPalette->GetPresentation() == presentation)
- gGlobals->fToolPalette->ClosePalette(ev);
- }
-
- // Locate the proxy, and remove it
- COrdListIterator fiter(fDisplayFrameProxies);
- for ( CDisplayFrameProxy* frameProxy = (CDisplayFrameProxy*)fiter.First();
- fiter.IsNotComplete();
- frameProxy = (CDisplayFrameProxy*)fiter.Next())
- {
- // shouldn't get called to remove a frame that has
- // not yet been internalized
- if (frameProxy->IsFrameInMemory())
- {
- if (frame==frameProxy->GetFrame(ev))
- {
- // Remove current makes the list consistent. This way
- // we can modify the list while we are iterating over
- // it.
- fiter.RemoveCurrent();
- delete frameProxy;
- }
- }
- }
-
- CATCH_ALL
- this->DoDialogBox(ev, frame, kErrorBoxID, kErrRemoveFrame);
-
- // Alert the caller.
- RERAISE;
- ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // Method: AttachSourceFrame
- // Origin: ODPart
- //
- // Description: If a part which we are contained in is opened into a
- // part window, it is required to iterate over its
- // embedded frames and add new display frames in the part
- // window. After each new embedded frame is created, this
- // method will be called.
- //
- // Given all that, and given our lack of interesting
- // content, we just validate the frame.
- //------------------------------------------------------------------------------
-
- void DrawEditor::AttachSourceFrame( Environment* ev,
- ODFrame* frame,
- ODFrame* sourceFrame )
- {
-
- SOM_Trace("DrawEditor","AttachSourceFrame");
-
- // Tell the new frame about its source.
- CFrameInfo* frameInfo = (CFrameInfo*) frame->GetPartInfo(ev);
- frameInfo->SetSourceFrame(ev, sourceFrame);
-
- // And tell the source about its new dependent.
- CFrameInfo* sourceFrameInfo = (CFrameInfo*) sourceFrame->GetPartInfo(ev);
- sourceFrameInfo->AttachFrame(ev, frame);
-
- // In both cases, refcounting of the frame and sourceFrame is
- // handled by the CFrameInfo class.
- }
-
-
- //------------------------------------------------------------------------------
- // Method: RemoveEmbeddedFrame
- // Origin: ODPart
- //
- // Description: This method is Called by an embedded part to indicate it no
- // longer needs the frame to display itself.
- //------------------------------------------------------------------------------
-
- void DrawEditor::RemoveEmbeddedFrame( Environment *ev, ODFrame* embeddedFrame )
- {
- SOM_Trace("DrawEditor","RemoveEmbeddedFrame");
-
- CShape* tShape = this->ShapeForFrame(ev, embeddedFrame);
- THROW_IF_NULL(tShape);
-
- if (tShape->IsSelected())
- {
- fSelection->RemoveFromSelection(ev, tShape, kODTrue); // Remove from Selection list
- }
- this->RemoveShape(ev, tShape); // Remove from shape list
-
- // Remove the shape from content, and put the frame in "limbo"
- tShape->SetInLimbo(ev, kODTrue);
- tShape->Removed(ev, kCommit);
- }
-
-
- //------------------------------------------------------------------------------
- // Method: ViewTypeChanged
- // Origin: ODPart
- //
- // Description: This method is called in response to one of our
- // display frame's viewType field being modified. We call
- // this method on ourselves when new display frames are
- // added, but it call also be called when the user
- // changes the view in the "part info" dialog.
- //
- // The part first loads the appropriate view icons if
- // needed and then calculates a new "used" shape based on
- // the bounds of the new view type. If any problems occur
- // while changing the view, the part defaults back to
- // frame view (the part's default view).
- //------------------------------------------------------------------------------
-
- void
- DrawEditor::ViewTypeChanged( Environment* ev,
- ODFrame* frame )
- {
- SOM_Trace("DrawEditor","ViewTypeChanged");
-
- ODTypeToken view = frame->GetViewType(ev);
-
- // Prepare to be displayed in a different view.
- if ( view == gGlobals->fThumbnailView )
- this->GenerateThumbnail(ev, frame);
-
- if ( view== gGlobals->fFrameView)
- {
- // Draw Content
- COrdListIterator iter(fShapeList);
- for (CShape* shape = (CShape*)iter.Last();
- iter.IsNotComplete();
- shape = (CShape*)iter.Previous())
- {
- shape->Show(ev, kODTrue);
- }
- }
- else
- {
- // Draw Content
- COrdListIterator iter(fShapeList);
- for (CShape* shape = (CShape*)iter.Last();
- iter.IsNotComplete();
- shape = (CShape*)iter.Previous())
- {
- // We must remove the shape from the selection if it is currently
- // selected since OpenDoc will send us an activate event which causes
- // the selection to be internalized.
- if (shape->IsSelected())
- {
- fSelection->RemoveFromSelection(ev, shape, kODFalse);
- }
- shape->Show(ev, kODFalse);
- }
- }
-
- // Change this frame's used shape to match the new view setting.
- TempODShape newUsedShape = this->CalcNewUsedShape(ev, frame);
-
- frame->Invalidate(ev, kODNULL, kODNULL);
- frame->ChangeUsedShape(ev, newUsedShape, kODNULL);
- frame->Invalidate(ev, kODNULL, kODNULL);
-
- }
-
- //------------------------------------------------------------------------------
- // Method: GenerateThumbnail
- // Origin: DrawEditor
- //
- // Description: This method is called by the part to generate a
- // thumbnail view from the current content.
- //
- // The part has no content, so we merely load a picture.
- //------------------------------------------------------------------------------
-
- void DrawEditor::GenerateThumbnail( Environment* ev,
- ODFrame* frame )
- {
- SOM_Trace("DrawEditor","GenerateThumbnail");
-
- // In cases where a part has been instantiated from scratch and has no
- // content (yet), it is appropriate to display a PICT or some graphic
- // in place of a "real" thumbnail.
-
- ::LoadThumbnail(ev, &gGlobals->fThumbnail);
-
- // If we were unable to load the PICT resource for whatever reason
- // we will default back to a "frame" view and throw the Resource
- // Manager error as an exception.
- if ( gGlobals->fThumbnail == kODNULL )
- {
- frame->ChangeViewType(ev, gGlobals->fFrameView);
-
- // There is a bug in ResError, when resources are not found,
- // which may cause noErr to be returned. If that is the case,
- // we throw resNotFound.
- THROW_IF_ERROR((ODError)ResError());
- THROW(resNotFound);
- }
- }
-
- //------------------------------------------------------------------------------
- // Method: UsedShapeChanged
- // Origin: ODPart
- //
- // Description: Containing parts which have wrapped content to the used shape of
- // an embedded frame will need to adjust the layout of that content for the new used shape.
- //------------------------------------------------------------------------------
-
- void DrawEditor::UsedShapeChanged( Environment *ev, ODFrame* embeddedFrame)
- {
- // Currently we do not support wrapping content to the used shape.
- SOM_Trace("DrawEditor","UsedShapeChanged");
- }
-
-
- //------------------------------------------------------------------------------
- // Method: FrameShapeChanged
- // Origin: ODPart
- //
- // Description: This method is called in response to a frame's shape being
- // altered, either by the user or the part we are embedded in.
- //
- // To keep all dependent frames in sync, we need to propogate the
- // new frame shape the frames dependent on the changed frame. This
- // is done by observing the display frames stored in the frame info
- // and calling RequestFrameShape for each.
- //------------------------------------------------------------------------------
-
- void DrawEditor::FrameShapeChanged( Environment* ev,
- ODFrame* frame )
- {
- SOM_Trace("DrawEditor","FrameShapeChanged");
-
- // Adjust the "used" shape for the new frame shape.
- TempODShape usedShape = this->CalcNewUsedShape(ev, frame);
- frame->ChangeUsedShape(ev, usedShape, kODNULL);
- }
-
-
-
- //------------------------------------------------------------------------------
- // Method: AcquireFramesWindow
- // Origin: DrawEditor
- //
- // Description: This method is called by the part when a frame, that has been
- // previously opened, is being opened again.
- //
- // The method retrieves the existing window for the frame and
- // returns it.
- //------------------------------------------------------------------------------
-
- ODWindow* DrawEditor::AcquireFramesWindow( Environment* ev,
- ODFrame* frame )
- {
- SOM_Trace("SamplePart","GetFramesWindow");
-
- CFrameInfo* frameInfo = (CFrameInfo*) frame->GetPartInfo(ev);
- ODWindow* window = frameInfo->GetPartWindow();
- ODAcquireObject(ev, window);
-
- return window;
- }
-
-
-
- //------------------------------------------------------------------------------
- // Method: Open
- // Origin: ODPart
- //
- // Description: This method is called when OpenDoc, a containing part,
- // or the active editor would like to open a frame into
- // a seperate window. If a source frame is passed into
- // this method, the editor is being asked to open a part
- // window.
- //
- // The part first checks to see if the display frame has
- // been opened into a window before (this will be true
- // if a source frame is passed in to the method and if
- // the source frame has a valid window ID). If there is
- // already a window displaying the frame, just bring that
- // window to the front. If not, we create a window from
- // scratch and display it.
- //------------------------------------------------------------------------------
-
- ODID DrawEditor::Open( Environment* ev,
- ODFrame* frame )
- {
- SOM_Trace("DrawEditor","Open");
-
- ODID windowID;
- ODWindow* window = kODNULL;
- WindowProperties* windowProperties = kODNULL;
-
- ODVolatile(window);
- ODVolatile(windowProperties);
-
- TRY
- // Because the frame parameter being passed to us can be one of
- // three things, we must determine what it is; either the root
- // frame of a existing document, the source frame for a part
- // window, or null if we are opening a new document.
-
- if ( frame == kODNULL )
- {
- // Calculate the bounding rectangle for a new window
- Rect windowRect = this->CalcPartWindowSize(ev, kODNULL);
- // Get the default setting for a document window.
- windowProperties = this->GetDefaultWindowProperties(ev, kODNULL, &windowRect);
- // Create a Mac Window and register it with OpenDoc.
- window = this->CreateWindow(ev, kODNULL, kODFrameObject, windowProperties);
- }
- else if ( frame->IsRoot(ev) )
- {
- // Get the previously saved settings for the document window.
- windowProperties = this->GetSavedWindowProperties(ev, frame);
-
- if ( windowProperties == kODNULL )
- {
- // Calculate the bounding rectangle for a new window
- Rect windowRect = this->CalcPartWindowSize(ev, frame);
- // Get the default setting for a document window.
- windowProperties = this->GetDefaultWindowProperties(ev, kODNULL, &windowRect);
- }
-
- // Create a Mac Window and register it with OpenDoc.
- window = this->CreateWindow(ev, frame, kODFrameObject, windowProperties);
-
- // We release the source frame here because we didn't call
- // EndGetWindowProperties and becuase we are done with it.
- // ODReleaseObject(ev, windowProperties->sourceFrame);
- }
- else // frame is a source frame
- {
- window = this->AcquireFramesWindow(ev, frame);
-
- if ( window == kODNULL )
- {
- // Calculate the bounding rectangle for a new window
- Rect windowRect = this->CalcPartWindowSize(ev, frame);
- // Get the default setting for a document window.
- windowProperties = this->GetDefaultWindowProperties(ev, frame, &windowRect);
- // Create a Mac Window and register it with OpenDoc.
- window = this->CreateWindow(ev, kODNULL, kODFrameObject, windowProperties);
-
- // Tell the source frame that it is opened in a part window.
- CFrameInfo* frameInfo = (CFrameInfo*) frame->GetPartInfo(ev);
- frameInfo->SetPartWindow(window);
- }
- }
-
- // Create the window's root facet.
- window->Open(ev);
- // Make the window visible.
- window->Show(ev);
- // Activate and select the window.
- window->Select(ev);
-
- // Cleanup allocate memory.
- ODDeleteObject(windowProperties);
-
- // Get window id to return.
- windowID = (window ? window->GetID(ev) : kODNULLID);
- ODReleaseObject(ev, window);
-
- CATCH_ALL
- // If we threw early, the source frame's refcount may be too high.
- if ( windowProperties )
- ODReleaseObject(ev, windowProperties->sourceFrame);
- // Cleanup the created items.
- ODDeleteObject(windowProperties);
- ODSafeReleaseObject(window);
- windowID = kODNULLID;
- // Alert the caller.
- RERAISE;
- ENDTRY
-
- return windowID;
- }
-
-
- //------------------------------------------------------------------------------
- // Method: CreateWindow
- // Origin: DrawEditor
- //
- // Description: This method is called by the part when a window needs to be
- // created for a frame being opened.
- //
- // The part uses the information passed in windowProperties to
- // create the appropriate window. The generated window is
- // registered with OpenDoc as a new window (RegisterWindow) or as a
- // window from an existing document (RegisterWindowForFrame).
- //------------------------------------------------------------------------------
-
- ODWindow* DrawEditor::CreateWindow( Environment* ev,
- ODFrame* frame,
- ODType frameType,
- WindowProperties* windowProperties)
- {
- SOM_Trace("DrawEditor","CreateWindow");
-
- ODPlatformWindow platformWindow = kODNULL;
- ODWindow* window = kODNULL;
-
- // Using the name and the calculated rectangle, create a new window.
- // Note that we are allocating the window record in temp mem using
- // the OpenDoc memory mgr. This helps reduce app heap usage.
- // In addition, OpenDoc requires that all new windows be initially hidden
- // so that it can correctly layer windows/palettes.
- platformWindow = ::NewCWindow((Ptr)::ODNewPtr(sizeof(WindowRecord)),
- &(windowProperties->boundsRect),
- windowProperties->title,
- kODFalse, /* visible */
- windowProperties->procID,
- (WindowPtr)-1L,
- windowProperties->hasCloseBox,
- windowProperties->refCon);
-
- if ( platformWindow )
- {
- TRY
- ODWindowState* windowState = ODGetSession(ev,fSelf)->GetWindowState(ev);
-
- // Shoud the window be saved in the document? Yes if the root frame is
- // persistent.
- ODBoolean saveWindow = (ODISOStrCompare(frameType,kODFrameObject) == 0);
-
- // Tell the window object that we will be disposing the window record
- // when the root frame is closed/removed.
- ODBoolean shouldDispose = kODFalse;
-
- // Determine whether we are creating a new window (frame is null),
- // or opening a previous saved window (frame is valid).
-
- if ( frame == kODNULL )
- {
- // Tell OpenDoc about it by creating an OpenDoc window object.
- window = windowState->
- RegisterWindow(ev,
- platformWindow, // Macintosh WindowPtr
- frameType, // Frame type (Persistent/Non-persistent)
- windowProperties->isRootWindow, // Is this a document window?
- windowProperties->isResizable, // Is this window resizeable?
- windowProperties->isFloating, // Is this window floating?
- saveWindow, // Should this window be persistent?
- shouldDispose, // (see comment above)
- fSelf, // Part reference to us
- gGlobals->fFrameView, // What view should the window have?
- gGlobals->fMainPresentation, // What presentation should the window have?
- windowProperties->sourceFrame); // The display frame being opened, if any
- }
- else
- {
- // Tell OpenDoc about it by creating an OpenDoc window object.
- window = windowState->
- RegisterWindowForFrame(ev,
- platformWindow, // Macintosh WindowPtr
- frame, // Frame type (Persistent/Non-persistent)
- windowProperties->isRootWindow, // Is this a document window?
- windowProperties->isResizable, // Is this window resizeable?
- windowProperties->isFloating, // Is this window floating?
- saveWindow, // Should this window be persistent?
- shouldDispose, // (see comment above)
- windowProperties->sourceFrame); // The display frame being opened, if any
- }
-
- CATCH_ALL
- // Cleanup Macintosh Window.
- CloseWindow(platformWindow);
- ODDisposePtr(platformWindow);
- // Get the right error message for the problem.
- ODSShort errMsgNum = (!frame && windowProperties->sourceFrame)
- ? kErrCantOpenPartWindow : kErrCantOpenDocWindow;
- // Alert the user of the problem.
- this->DoDialogBox(ev, frame, kErrorBoxID, errMsgNum);
- // Change the exception value, so the DocShell doesn't display an
- // error dialog.
- SetErrorCode(kODErrAlreadyNotified);
- // Alert the caller.
- RERAISE;
- ENDTRY
- }
-
- return window;
- }
-
- //------------------------------------------------------------------------------
- // Method: CleanupWindow
- // Origin: DrawEditor
- //
- // Description: This method is called by the part when a window needs to be
- // cleaned up for a frame being closed/removed.
- //
- // The part deallocates the window buffer allocated in the
- // CreateWindow() method.
- //------------------------------------------------------------------------------
-
- void DrawEditor::CleanupWindow( Environment* ev,
- ODFrame* frame )
- {
- SOM_Trace("DrawEditor","CleanupWindow");
-
- TRY
- CFrameInfo* frameInfo = (CFrameInfo*) frame->GetPartInfo(ev);
- if ( frameInfo->ShouldDisposeWindow() )
- {
- TempODWindow window = frame->AcquireWindow(ev);
- THROW_IF_NULL(window);
-
- ODPlatformWindow windowPtr = window->GetPlatformWindow(ev);
- CloseWindow(windowPtr);
- ODDisposePtr(windowPtr);
- }
- CATCH_ALL
- this->DoDialogBox(ev, frame, kErrorBoxID, kErrWindowGone);
- // consume excpetion because it's not fatal.
- ENDTRY
- }
-
-
- //------------------------------------------------------------------------------
- // Method: GetDefaultWindowProperties
- // Origin: DrawEditor
- //
- // Description: This method is called by the part when a new window is being
- // created. The method examines the frame which is being opened
- // a generates the default window parameters to pass to the
- // Mac Toolbox.
- //------------------------------------------------------------------------------
-
- WindowProperties*
- DrawEditor::GetDefaultWindowProperties( Environment* ev,
- ODFrame* sourceFrame,
- Rect* windowRect )
- {
- SOM_Trace("DrawEditor","GetDefaultWindowProperties");
-
- WindowProperties* windowProperties = new WindowProperties;
- ODIText* windowName;
-
- // Calculate the offset for the window based on the sourceFrame.
- if ( sourceFrame )
- this->CalcPartWindowPosition(ev, sourceFrame, windowRect);
- else
- OffsetRect(windowRect, kALittleNudge,
- GetMBarHeight() + kMacWindowTitleBarHeight);
-
- windowProperties->boundsRect = *windowRect;
-
- // Get the part name to use for the new window. If we can't
- // get a valid name for the part, we generate one using the user
- // visible category name of the part's category.
- windowName = ODGetITextProp(ev, fSelf->GetStorageUnit(ev), kODPropName,
- kODMacIText, kODNULL);
-
- if ( (windowName == kODNULL) || (GetITextStringLength(windowName) == 0) )
- {
- ODNameSpaceManager* nsMgr = ODGetSession(ev,fSelf)->GetNameSpaceManager(ev);
-
- // Get the category string from the category name space.
- if ( !GetUserCatFromCat(nsMgr, kODCategoryDrawing, &windowName) )
- #if ODDebug
- // This should never happen. Check NMAP for errors.
- DebugStr("\pCategory NMAP bad, or Preferences corrupted.");
- #else
- THROW(kODErrInvalidNSType);
- #endif
- }
-
- // Convert the ODIText into a Pascal string.
- GetITextString(windowName, windowProperties->title);
- // Dispose of the name object.
- DisposeIText(windowName);
-
- // Fill in the other fields of the Window Properties struct.
-
- windowProperties->procID = zoomDocProc;
- windowProperties->hasCloseBox = kODTrue;
- windowProperties->refCon = (long) kODNULL;
- windowProperties->wasVisible = kODFalse;
- windowProperties->isResizable = kODTrue;
- windowProperties->isFloating = kODFalse;
- windowProperties->isRootWindow = sourceFrame ? kODFalse : kODTrue;
- windowProperties->shouldShowLinks = kODFalse;
- windowProperties->sourceFrame = sourceFrame;
-
- return windowProperties;
- }
-
- //------------------------------------------------------------------------------
- // Method: GetSavedWindowProperties
- // Origin: DrawEditor
- //
- // Description: This method is called by the part to read in saved information
- // for a window from an existing document.
- //------------------------------------------------------------------------------
-
- WindowProperties*
- DrawEditor::GetSavedWindowProperties( Environment* ev,
- ODFrame* frame )
- {
- SOM_Trace("DrawEditor","GetSavedWindowProperties");
-
- WindowProperties* windowProperties = new WindowProperties;
-
- // If we fail to load the window properties from storage, delete
- // the structure so the calling code will behave appropriately.
- if ( !BeginGetWindowProperties(ev, frame, windowProperties) )
- {
- ODDeleteObject(windowProperties);
- EndGetWindowProperties(ev, windowProperties);
- return kODNULL;
- }
- else
- EndGetWindowProperties(ev, windowProperties);
-
- // Note: We don't call EndGetWindowProperties because it releases the
- // source frame, which we will need after this method returns.
-
- // Verify the window is still visible on a monitor.
-
- RgnHandle windowRgn = ODNewRgn();
- ODBoolean repositionWindow = kODFalse;
-
- // We are only concerned with the window's title bar being
- // visible, so calcuate the titlebar rect from the current
- // window bounds.
- Rect adjustedBounds = windowProperties->boundsRect;
- adjustedBounds.bottom = adjustedBounds.top;
- adjustedBounds.top -= kMacWindowTitleBarHeight;
-
- // Intersect the monitor's region
- RectRgn(windowRgn, &adjustedBounds);
- SectRgn(windowRgn, GetGrayRgn(), windowRgn);
-
- if ( !EmptyRgn(windowRgn) )
- {
- // If the visible portion of the window is too small, we need
- // to reposition it.
- Rect intersectedBounds = (**windowRgn).rgnBBox;
- if ( (intersectedBounds.right-intersectedBounds.left < kMinHorzVisPortion) ||
- (intersectedBounds.bottom-intersectedBounds.top < kMinVertVisPortion) )
- repositionWindow = kODTrue;
- }
- else
- {
- // If the window is completely offscreen, we need to reposition it.
- repositionWindow = kODTrue;
- }
- ODDisposeHandle((ODHandle)windowRgn);
-
- // If not, we need to move it so the user can see it.
- if ( repositionWindow )
- {
- Rect windowRect = (windowProperties->boundsRect);
- // Move the window to {0,0} coordinates.
- OffsetRect(&windowRect, -windowRect.left, -windowRect.top);
- // Now move the window to the default window position.
- OffsetRect(&windowRect, kALittleNudge, GetMBarHeight() + kMacWindowTitleBarHeight);
- // Save the new window position in our windowProperties.
- windowProperties->boundsRect = windowRect;
- }
-
- return windowProperties;
- }
-
- //------------------------------------------------------------------------------
- // Method: CalcPartWindowSize
- // Origin: DrawEditor
- //
- // Description: This method is called by the part to determine what
- // size a new window should be.
- //------------------------------------------------------------------------------
-
- Rect DrawEditor::CalcPartWindowSize( Environment* ev,
- ODFrame* sourceFrame )
- {
- SOM_Trace("DrawEditor","CalcPartWindowSize");
-
- const ODSShort kOnePageWidth = 600;
-
- Rect windowRect;
- ODRect frameRect;
-
- // If a source frame is given, the part is being asked to open one of
- // its display frames into a part window. Otherwise, we are being opened
- // as the root frame of the current document and should size the window
- // accordingly.
-
- // Set up the child window's size to be that of the display frame being opened.
- if ( sourceFrame )
- {
- // Retrieve the fixed point bounding box for the frame.
- ODShape* frameShape = sourceFrame->AcquireFrameShape(ev, kODNULL);
- frameShape->GetBoundingBox(ev, &frameRect);
-
- // Convert that into a Quickdraw rectangle.
- FixedToIntRect(frameRect, windowRect);
-
- ODReleaseObject(ev,frameShape);
- }
- // Otherwise, just open a large window.
- else
- {
- // (3 * kODLargeIconSize) prevents the window from covering the volume
- // icons on the desktop which is a violation of Macintosh HI Guidelines.
-
- SetRect(&windowRect, 0, 0,
- ODQDGlobals.screenBits.bounds.right - (3 * kODLargeIconSize),
- ODQDGlobals.screenBits.bounds.bottom
- - GetMBarHeight() - kMacWindowTitleBarHeight - kALittleNudge);
-
- if ( windowRect.right - windowRect.left > kOnePageWidth )
- windowRect.right = windowRect.left + kOnePageWidth;
- }
-
- return windowRect;
- }
-
- //------------------------------------------------------------------------------
- // Method: CalcPartWindowPosition
- // Origin: DrawEditor
- //
- // Description: This method is called by the part to determine where
- // to align the new window (top left corner of the screen
- // or tiled to a frame).
- //------------------------------------------------------------------------------
-
- Rect DrawEditor::CalcPartWindowPosition( Environment* ev,
- ODFrame* frame,
- Rect* partWindowBounds )
- {
- SOM_Trace("DrawEditor","CalcPartWindowPosition");
-
- ODFacet* activeFacet;
- ODShape* frameShape;
- ODRect bbox;
- Rect bounds;
-
- // We need to know which facet of the frame we are opening to position
- // the child window.
- activeFacet = this->GetActiveFacetForFrame(ev, frame);
-
- // This should never occur, but if it did, it would be fatal.
- // So we will just pass back the same rectangle.
- if ( activeFacet == kODNULL )
- return *partWindowBounds;
-
- // For the purposes of tiling, we need the to know the area of the
- // document the frame occupies. We do this by getting the bouding
- // box and offsetting it by the aggregate external window transform
- // of the facet.
-
- frameShape = activeFacet->GetFrame(ev)->AcquireFrameShape(ev, kODNULL);
- TempODTransform windowFrameTransform = activeFacet->AcquireWindowFrameTransform(ev, kODNULL);
- TempODShape boundsShape = ODCopyAndRelease(ev, frameShape);
-
- // Translate the bounds rect into window coordinates.
- boundsShape->Transform(ev, windowFrameTransform);
-
- // Get and convert the bounding box into a QuickDraw rectangle.
- boundsShape->GetBoundingBox(ev, &bbox);
- FixedToIntRect(bbox, bounds);
-
- // We then call our method to tile the child window.
- *partWindowBounds = TilePartWindow(ev, &bounds, partWindowBounds);
-
- // Set the port and origin so we can convert the rect to
- // global Window Mgr coordinates.
- SetPort(activeFacet->GetCanvas(ev)->GetQDPort(ev));
- SetOrigin(0,-kMacWindowTitleBarHeight);
-
- // Convert the local coordinates to global Window Mgr coordinates.
- LocalToGlobal((Point*)(&(partWindowBounds->top)));
- LocalToGlobal((Point*)(&(partWindowBounds->bottom)));
-
- return *partWindowBounds;
- }
-
- //------------------------------------------------------------------------------
- // Method: GetActiveFacetForFrame
- // Origin: DrawEditor
- //
- // Description: This method is called by the part when it needs to
- // know what the active facet is for the part, if any.
- //
- // The part uses this method specifically to find the
- // facet of a source frame when opening a part window.
- //------------------------------------------------------------------------------
-
- ODFacet* DrawEditor::GetActiveFacetForFrame( Environment* ev,
- ODFrame* frame )
- {
- SOM_Trace("DrawEditor","GetActiveFacetForFrame");
-
- ODFacet* facet = kODNULL;
- CFrameInfo* frameInfo = (CFrameInfo*) frame->GetPartInfo(ev);
-
- // If the frame is active, and it should be, get the active facet
- // from the frame state info.
- if ( frameInfo->IsFrameActive() )
- {
- facet = frameInfo->GetActiveFacet();
- }
- else
- // Otherwise, iterate over the display frames looking for one
- // that has an active facet... there should be at least one.
- {
- ODFacet* selectedFacet;
- ODBoolean foundSelectedFacet = kODFalse;
-
- ODFrameFacetIterator* fiter = frame->CreateFacetIterator(ev);
- for ( selectedFacet = fiter->First(ev);
- fiter->IsNotComplete(ev);
- selectedFacet = fiter->Next(ev) )
- {
- if ( selectedFacet->IsSelected(ev) )
- {
- foundSelectedFacet = kODTrue;
- break;
- }
- }
-
- facet = selectedFacet;
-
- ODDeleteObject(fiter);
- }
-
- return facet;
- }
-
- //------------------------------------------------------------------------------
- // Method: CalcNewUsedShape
- // Origin: DrawEditor
- //
- // Description: This method is called in response to one of display frame's view
- // being changed. The method calculates the appropriate usedShape
- // for the new view type.
- //------------------------------------------------------------------------------
-
- ODShape* DrawEditor::CalcNewUsedShape( Environment* ev,
- ODFrame* frame )
- {
- SOM_Trace("DrawEditor","CalcNewUsedShape");
-
- ODShape* usedShape = kODNULL; ODVolatile(usedShape);
- RgnHandle usedRgn; ODVolatile(usedRgn);
-
- // If the view is "frame", we intentionally return a nil shape;
- // doing so, will reset the used shape to equal the frame shape.
-
- ODTypeToken view = frame->GetViewType(ev);
-
- if ( view == gGlobals->fLargeIconView ||
- view == gGlobals->fSmallIconView ||
- view == gGlobals->fThumbnailView )
- {
- TRY
- Rect bounds;
- usedRgn = ODNewRgn();
-
- if ( view == gGlobals->fLargeIconView || view == gGlobals->fSmallIconView )
- {
- CUsingLibraryResources res;
-
- // Set the bounds rect for the icon size.
- SetRect(&bounds, 0, 0,
- (view == gGlobals->fLargeIconView) ? kODLargeIconSize : kODSmallIconSize,
- (view == gGlobals->fLargeIconView) ? kODLargeIconSize : kODSmallIconSize);
-
- // Convert the icon mask into a Region.
- THROW_IF_ERROR( IconIDToRgn(usedRgn, &bounds, atAbsoluteCenter, kBaseResourceID) );
- }
- else if ( view == gGlobals->fThumbnailView )
- {
- bounds = (**(PicHandle)gGlobals->fThumbnail).picFrame;
- RectRgn(usedRgn,&bounds);
- }
-
- usedShape = frame->CreateShape(ev);
- usedShape->SetQDRegion(ev, usedRgn);
-
- CATCH_ALL
- ODSafeReleaseObject(usedShape);
- ODDisposeHandle((ODHandle)usedRgn);
- usedShape = kODNULL;
- ENDTRY
- }
-
- return usedShape;
- }
-
- //------------------------------------------------------------------------------
- // Origin: DrawEditor
- //
- // Description: This method is called in response to one of our
- //------------------------------------------------------------------------------
-
- void
- DrawEditor::UpdateFrame( Environment* ev,
- ODFrame* frame,
- ODTypeToken view,
- ODShape* usedShape )
- {
- SOM_Trace("DrawEditor","UpdateFrame");
-
- // Update the frame to have the new view and UsedShape.
- frame->Invalidate(ev, kODNULL, kODNULL);
- frame->SetViewType(ev, view);
- frame->ChangeUsedShape(ev, usedShape, kODNULL);
- frame->Invalidate(ev, kODNULL, kODNULL);
- }
-
- //------------------------------------------------------------------------------
- // Method: FacetAdded
- // Origin: ODPart
- //
- // Description: This method is called when any part adds a facet to
- // one of our display frames.
- //
- // The part calls ViewTypeChanged to load the appropriate
- // resource for display in this facet and then activates
- // the frame if we are the root part of an active window.
- //------------------------------------------------------------------------------
-
- void DrawEditor::FacetAdded( Environment* ev,
- ODFacet* facet )
- {
- SOM_Trace("DrawEditor","FacetAdded");
-
- ODFrame* frame = facet->GetFrame(ev);
- CFrameInfo* frameInfo = (CFrameInfo*) frame->GetPartInfo(ev);
-
- ODBoolean isMainPresentation = facet->GetFrame(ev)->
- GetPresentation(ev)==gGlobals->fMainPresentation;
-
- // Notify our embedded content of the new facet, Only if it is not a palette
- if (isMainPresentation)
- {
- COrdListIterator iter(fShapeList);
- if (fShapeList)
- for ( CShape* shape = (CShape*)iter.First();
- iter.IsNotComplete();
- shape = (CShape*)iter.Next() )
- {
- shape->FacetAdded(ev, facet);
- }
-
- // We call this to prepare our part for being displayed in one of
- // the four standard views: Large Icon, Small Icon, Frame, and
- // Thumbnail.
- this->ViewTypeChanged(ev, frame);
-
- // If this is the root frame/facet of a given window and it is NOT in a palette
- // we should activate ourselves.
- if (frame->IsRoot(ev))
- {
- if ( this->ActivateFrame(ev, frame) )
- frameInfo->SetActiveFacet(facet);
- }
-
- // If a frame had all of its facets removed, the frame would have
- // hidden any of its part windows. If the frame becomes visible again,
- // by having a facet added to it, we will "show" the part window for
- // the frame. Except, in the case where are a frame could be scrolled out of view,
- // and purged. When scrolling is implemented this will need to change.
-
- if ( (CountFramesFacets(ev, frame) == 1) )
- {
- if ( frameInfo->HasPartWindow() )
- frameInfo->GetPartWindow()->Show(ev);
- }
-
- // Only clip the facet if it is not a palette
- this->ClipEmbeddedFacets(ev, facet);
-
- }
-
- }
-
- //------------------------------------------------------------------------------
- // Method: FacetRemoved
- // Origin: ODPart
- //
- // Description: This method is called when any part removes a facet
- // from one of our display frames.
- //
- // The part just removes the "active" note from the
- // appropriate display frame if necessary since this
- // facet will not be available, nor active, again.
- //------------------------------------------------------------------------------
-
- void DrawEditor::FacetRemoved( Environment* ev,
- ODFacet* facet )
- {
- SOM_Trace("DrawEditor","FacetRemoved");
-
- ODFrame* frame = facet->GetFrame(ev);
- CFrameInfo* frameInfo = (CFrameInfo*) frame->GetPartInfo(ev);
-
- ODBoolean isMainPresentation = frame->GetPresentation(ev)==gGlobals->fMainPresentation;
-
- // If the facet was the active facet, it can no longer be.
- if ( frameInfo->GetActiveFacet() == facet )
- frameInfo->SetActiveFacet(kODNULL);
-
- // If a frame has all of its facets removed, the frame becomes
- // "hidden". If the frame a part window, the part window should also
- // be hidden. This may need to change when scrolling is implemented.
- // The case where a frame is scrolled out of view and purged temprorarily, its
- // part window may remain visible.
-
-
- if (isMainPresentation)
- {
- if ( (CountFramesFacets(ev, frame) == 0) )
- {
- if ( frameInfo->HasPartWindow() )
- frameInfo->GetPartWindow()->Hide(ev);
- }
-
- // Remove any embedded facets of the given facet
- COrdListIterator iter(fShapeList);
- if (fShapeList)
- for ( CShape* shape = (CShape*)iter.First();
- iter.IsNotComplete();
- shape = (CShape*)iter.Next() )
- {
- shape->FacetRemoved(ev, facet);
- }
- }
-
- }
-
- //------------------------------------------------------------------------------
- // Method: RequestFrameShape
- // Origin: ODPart
- //
- // Description: An embedded part has asked to change the shape of its frame.
- //
- //------------------------------------------------------------------------------
-
- ODShape* DrawEditor::RequestFrameShape(Environment *ev, ODFrame* embeddedFrame,
- ODShape* frameShape)
- {
- // Grant any shape, for the time being
-
- ODShape* contentShape = kODNULL;
-
- TRY
- // First make a copy of the incoming shape
- contentShape = frameShape->Copy(ev);
-
- // Find the shape representing the given frame and resize it
- CShape* tShape = this->ShapeForFrame(ev, embeddedFrame);
- THROW_IF_NULL(tShape);
-
- // Transform the shape before setting the content bounds
- Point offset;
- Rect tRect;
-
- tShape->GetBoundingBox(&tRect);
- offset.h = tRect.left;
- offset.v = tRect.top;
-
- TempODTransform tTransform = embeddedFrame->CreateTransform(ev);
- tTransform->SetQDOffset(ev, &offset);
- contentShape->Transform(ev, tTransform);
-
- // Change the embedded content's bounding rectangle, without
- // causing the actual ODFrame to be resized.
- if (tShape->GetShapeType() == kEmbeddingShape)
- {
- ((CEmbeddingShape*)tShape)->SetShapeRectangle(ev, contentShape);
- }
- #ifdef ODDebug
- else
- DebugStr("\pThis shape really should be an embedding shape!");
- #endif
-
- // Redraw the shape with its new bounds
- this->InvalidateShape(ev, tShape);
-
- CATCH_ALL
- #ifdef ODDebug
- DebugStr("\pThis frame is NOT embedded in this part!");
- #endif
-
- return kODNULL;
- ENDTRY
-
- // The leaf part will release this shape
- ODAcquireObject(ev, frameShape);
- return frameShape;
- }
-
-
- //------------------------------------------------------------------------------
- // Method: RequestEmbeddedFrame
- // Origin: ODPart
- //
- // Description: An embedded part has asked for an additional frame.
- //
- //------------------------------------------------------------------------------
- ODFrame* DrawEditor::RequestEmbeddedFrame(Environment* ev,
- ODFrame* containingFrame,
- ODFrame* baseFrame,
- ODShape* frameShape,
- ODPart* embedPart,
- ODTypeToken viewType,
- ODTypeToken presentation,
- ODBoolean isOverlaid)
- {
- // Create a new content shape for the new frame
- // Grant any shape, for the time being
- ODRgnHandle tODRegion = frameShape->GetQDRegion(ev);
- Rect shapeBounds = (*tODRegion)->rgnBBox;
-
- CEmbeddingShape* newShape = (CEmbeddingShape*)(this->CreateShape(ev, kEmbeddingShape, shapeBounds));
- THROW_IF_NULL(newShape);
-
- // Make a proxy for it
- CEmbeddedFrameProxy* frameProxy = new CEmbeddedFrameProxy();
- frameProxy->InitializeEmbeddedFrameProxy(ev,
- this,
- newShape,
- containingFrame,
- embedPart,
- viewType,
- presentation);
-
- THROW_IF_NULL(frameProxy);
-
- // Add the proxy to the shape
- newShape->AddFrameProxy(frameProxy);
-
- // Add the shape to the document
- this->AddShape(ev, newShape);
-
- ODFrame* resultFrame = frameProxy->GetFrame(ev);
- THROW_IF_NULL(resultFrame);
-
- // Assign Frame group and sequence IDs
-
- // First check to see if the base frame is grouped
- ODULong tGroup = baseFrame->GetFrameGroup(ev);
-
- // If the group is zero, then it is not a part of a group
- // Create a unique group for the base frame AND the new frame
- if (tGroup==0L)
- {
- // Get new group ID
- tGroup = this->GetNewGroupID();
-
- // Set BOTH frames to this new group
- baseFrame->SetFrameGroup(ev, tGroup);
- resultFrame->SetFrameGroup(ev, tGroup);
-
- // Since we have created a new group, then it's obvious that the
- // base frame is sequence #1 and resultFrame is 2.
- baseFrame->ChangeSequenceNumber(ev, 1L);
- resultFrame->ChangeSequenceNumber(ev, 2L);
- }
- else
- // Base frame is already grouped
- {
- // Make the newly created frame be in the base frames group
- resultFrame->SetFrameGroup(ev, tGroup);
-
- // Set the sequence number of the frame to the next in the series
- ODULong sequenceCount = frameProxy->FindNextSequence(ev, tGroup);
- resultFrame->ChangeSequenceNumber(ev, sequenceCount+1);
- }
-
- return resultFrame;
- }
-
-
- //------------------------------------------------------------------------------
- // Method: InvalidateActiveBorder
- // Origin: DrawEditor
- //
- // Description: .
- //
- //------------------------------------------------------------------------------
- void DrawEditor::InvalidateActiveBorder(Environment *ev, ODFrame *frame)
- {
- if (fActiveBorderShape)
- {
- frame->Invalidate(ev, fActiveBorderShape, kODNULL);
- }
- }
-
- //------------------------------------------------------------------------------
- // Method: AdjustBorderShape
- // Origin: ODPart
- //
- // Description: .
- //
- //------------------------------------------------------------------------------
- ODShape* DrawEditor::AdjustBorderShape(Environment *ev,
- ODFacet *embeddedFacet, ODShape* borderShape)
- {
- ODFacet* containingFacet = embeddedFacet->GetContainingFacet(ev);
- ODCanvas* tBiasCanvas = containingFacet->GetCanvas(ev);
-
- // The active border is moving to a new frame
- // Get rid of our saved copy and return kODNULL to OpenDoc per recipe.
- if (borderShape == kODNULL)
- {
- // OpenDoc appears to be calling us twice in a row with a null bordershape
- ODReleaseObject(ev,fActiveBorderShape);
- fActiveBorderShape = kODNULL;
-
- this->ClipEmbeddedFacets(ev, containingFacet);
- return kODNULL;
- }
-
- ODTransform* tTransform = kODNULL;
- ODShape* tShape = kODNULL;
- ODShape* adjusted = borderShape->Copy(ev);
-
- // Put our copy of the given shape into frame coordinates
- tTransform = embeddedFacet->AcquireExternalTransform(ev, tBiasCanvas);
- adjusted->Transform(ev, tTransform);
- ODReleaseObject(ev,tTransform);
-
- // Find the intersection of the adjusted shape and the display facet
- ODShape* displayShape = containingFacet->GetFrame(ev)->AcquireUsedShape(ev, tBiasCanvas);
- adjusted->Intersect(ev, displayShape);
- ODReleaseObject(ev,displayShape);
-
- ODFacet* facet = kODNULL;
- ODBoolean above = kODFalse;
-
- COrdListIterator iter(fShapeList);
- for (CShape* shape = (CShape*)iter.Last();
- iter.IsNotComplete();
- shape = (CShape*)iter.Previous())
- {
- // Clip native content
- if (shape->GetShapeType()!=kEmbeddingShape)
- {
- if (above)
- {
- TempODShape tShape = embeddedFacet->CreateShape(ev);
- ODRgnHandle tRegion = shape->GetBoundingRegion();
- tShape->SetQDRegion(ev, tRegion);
- adjusted->Subtract(ev, tShape);
- }
-
- }
- else
- // Clip embedded content
- {
- facet = ((CEmbeddingShape*)shape)->GetEmbeddedFacet(ev, containingFacet);
-
- if (above)
- {
- tShape = ODCopyAndRelease(ev, facet->GetFrame(ev)->AcquireUsedShape(ev, tBiasCanvas));
- tTransform = facet->AcquireExternalTransform(ev, tBiasCanvas);
- tShape->Transform(ev, tTransform);
- adjusted->Subtract(ev, tShape);
- ODReleaseObject(ev,tShape);
- ODReleaseObject(ev,tTransform);
- }
- else
- above = (ODObjectsAreEqual(ev, facet, embeddedFacet));
- }
- }
-
- if (fActiveBorderShape == kODNULL)
- {
- fActiveBorderShape = adjusted->Copy(ev);
- }
-
- // Put adjusted shape into frame coordinates
- tTransform = embeddedFacet->AcquireExternalTransform(ev, tBiasCanvas);
- adjusted->InverseTransform(ev, tTransform);
- ODReleaseObject(ev,tTransform);
-
- this->ClipEmbeddedFacets(ev, containingFacet);
-
- return adjusted;
- }
-
- //------------------------------------------------------------------------------
- // Method: ClipEmbeddedFacets
- // Origin: DrawEditor
- //
- // Description: Iterate over & clip all facets for the given frame.
- //
- //------------------------------------------------------------------------------
-
- void DrawEditor::ClipEmbeddedFacets(Environment *ev, ODFrame* containingFrame)
- {
- #ifdef qProfileDrawEditor
- // $$$$$ DCS Profiling
- :: ProfilerSetStatus(kODTrue);
- #endif
-
-
- // Clip embedded facets for all facets of this frame
- ODFrameFacetIterator* facets = containingFrame->CreateFacetIterator(ev);
- for (ODFacet* facet = facets->First(ev); facets->IsNotComplete(ev);
- facet = facets->Next(ev))
- this->ClipEmbeddedFacets(ev, facet);
-
- delete facets;
-
- #ifdef qProfileDrawEditor
- // $$$$$ DCS Profiling
- :: ProfilerSetStatus(kODFalse);
- #endif
-
- }
- //------------------------------------------------------------------------------
- // Method: ClipEmbeddedFacets
- // Origin: DrawEditor
- //
- // Description: Clip content away from facets embedded within the given
- // facet.
- //
- //------------------------------------------------------------------------------
-
- void DrawEditor::ClipEmbeddedFacets(Environment *ev, ODFacet* containingFacet)
- {
- SOM_Trace("DrawEditor","ClipEmbeddedFacets");
-
- ODCanvas* tBiasCanvas = containingFacet->GetCanvas(ev);
- ODGeometryMode tGeoMode = GetCanvasGeometryMode(ev, tBiasCanvas);
- ODShape* workingClip =
- ODCopyAndRelease(ev, containingFacet->AcquireClipShape(ev, tBiasCanvas));
- THROW_IF_NULL(workingClip);
-
- // We can only embed into our main presentation,
- // so return if this facet doesn't belong to it
- ODTypeToken presentation = containingFacet->GetFrame(ev)->GetPresentation(ev);
- if (presentation != gGlobals->fMainPresentation)
- return;
-
- ODFacet* embeddedFacet = kODNULL;
- ODShape* newClipShape = kODNULL;
- ODShape* newMaskShape = kODNULL;
- ODShape* tShape = containingFacet->CreateShape(ev);
- ODRgnHandle tRegion = kODNULL;
- ODTransform* clipTransform = kODNULL;
-
- // Compute the clip by iterating over all content, native and embedded
- COrdListIterator iter(fShapeList);
- for (CShape* shape = (CShape*)iter.First();
- iter.IsNotComplete();
- shape = (CShape*)iter.Next())
- {
- // Clip native content
- if (shape->GetShapeType()!=kEmbeddingShape)
- {
- tRegion = shape->GetBoundingRegion();
- tShape->SetQDRegion(ev, tRegion);
- workingClip->Subtract(ev, tShape);
- }
- else
- // Clip embedded content
- {
- embeddedFacet = ((CEmbeddingShape*)shape)->GetEmbeddedFacet(ev, containingFacet);
-
- // Start with the facets FrameShape
- newClipShape = ODCopyAndRelease(ev,
- embeddedFacet->GetFrame(ev)->AcquireFrameShape(ev, tBiasCanvas));
- newClipShape->SetGeometryMode(ev, tGeoMode);
-
- // Get used shape to obscure underlying facets
- newMaskShape = ODCopyAndRelease(ev,
- embeddedFacet->GetFrame(ev)->AcquireUsedShape(ev, tBiasCanvas));
-
- clipTransform = embeddedFacet->AcquireExternalTransform(ev, tBiasCanvas);
-
- // Put into containing frame coordinates
- newClipShape->Transform(ev, clipTransform);
- newClipShape->Intersect(ev, workingClip);
-
- // Put into embedded frame coordinates
- newClipShape->InverseTransform(ev, clipTransform);
- embeddedFacet->ChangeGeometry(ev, newClipShape, kODNULL, tBiasCanvas);
-
- newMaskShape->Transform(ev, clipTransform);
- workingClip->Subtract(ev, newMaskShape);
-
- // Release acquired geometry
- ODReleaseObject(ev,newClipShape);
- ODReleaseObject(ev,newMaskShape);
- ODReleaseObject(ev,clipTransform);
- }
- }
-
- // Release acquired geometry
- ODReleaseObject(ev,workingClip);
- ODReleaseObject(ev,tShape);
- }
-
-
-
- //------------------------------------------------------------------------------
- // Method: Draw
- // Origin: ODPart
- //
- // Description: This method is called when a facet of a part's display
- // frame intersects the invalidated portion of an OpenDoc
- // window. The invalidShape parameter passed in is the
- // portion of the facet which has been invalidated.
- //
- // The part sets up the drawing environment using a
- // C++ helper class (CFocusDrawingEnv) and then calls the
- // appropriate drawing method based on the frame's
- // viewType.
- //------------------------------------------------------------------------------
-
- void DrawEditor::Draw( Environment* ev,
- ODFacet* facet,
- ODShape* invalidShape )
- {
- SOM_Trace("DrawEditor","Draw");
-
-
- // Focus the port and origin for drawing in our facet.
- // Note that this instance of the CFocusDrawingEnv class
- // is being allocated on the stack. When the execution
- // leaves the scope of this method, the destructor (which
- // cleans up the drawing environment) is automatically
- // called.
- CFocus initiateDrawing(ev, facet, invalidShape);
-
- // Check the presentation we are being requested to draw
- ODTypeToken presentation = facet->GetFrame(ev)->GetPresentation(ev);
-
- // If its the main presentation, then check the view type of the
- // frame and draw it.
- if (presentation == gGlobals->fMainPresentation)
- {
- ODTypeToken view = facet->GetFrame(ev)->GetViewType(ev);
-
- if ( view == gGlobals->fLargeIconView || view == gGlobals->fSmallIconView )
- this->DrawIconView(ev, facet);
- else if ( view == gGlobals->fThumbnailView )
- this->DrawThumbnailView(ev, facet);
- else
- this->DrawFrameView(ev, facet, invalidShape);
- }
-
- // If its one of our palettes then go ahead and draw it,
- // palettes don't have multiple view types.
- // Should I not draw palettes if the main frame is viewed
- // as other than frame ????? DCS
- else
- if (presentation == gGlobals->fColorPalette->GetPresentation())
- gGlobals->fColorPalette->Draw(ev, facet, invalidShape);
- else
- if (presentation == gGlobals->fToolPalette->GetPresentation())
- gGlobals->fToolPalette->Draw(ev, facet, invalidShape);
- }
-
- //------------------------------------------------------------------------------
- // Method: DrawGrid
- // Origin: DrawEditor
- //
- // Description: This method simply draws a grid pattern in the frame.
- // We assume that we are currently focused when this method is called.
- //
- //------------------------------------------------------------------------------
-
- void DrawEditor::DrawGrid( Environment* ev, ODFrame* frame )
- {
- SOM_Trace("DrawEditor","DrawGrid");
-
- ODShape* frameShape;
- RgnHandle frameRgn;
- Rect frameRect;
-
- // Grid Pattern
- // Pattern vertical = {0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- Pattern vertical = {0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- Pattern horizontal = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80};
-
- // Grid Size, color
- const ODSShort kGridSize = 72;
- const ODSShort kGridColor = 162;
-
- // Get frame bounds for drawing.
- frameShape = frame->AcquireFrameShape(ev, kODNULL);
- frameRgn = frameShape->GetQDRegion(ev);
- frameRect = (*frameRgn)->rgnBBox;
-
- // Get the bounds we are drawing into
- ODSShort minY = frameRect.top;
- ODSShort maxY = frameRect.bottom;
- ODSShort minX = frameRect.left;
- ODSShort maxX = frameRect.right;
-
- // Save state
- PenState tPen;
- RGBColor tColor;
- GetPenState(&tPen);
- GetForeColor(&tColor);
-
- // Set the pen for the vertical pattern
- PenPat(&vertical);
-
- // Set the grid color
- CRGBColor color;
- gGlobals->fColorPalette->GetColor(kGridColor, &color);
- RGBForeColor((RGBColor*)&color);
-
- // Draw the vertical lines
- for (ODSShort x = minX; x <= maxX; x += kGridSize)
- {
- MoveTo(x,minY);
- LineTo(x,maxY);
- }
-
- // Set the pen for the horizontal pattern
- PenPat(&horizontal);
-
- // Draw the horizontal lines
- for (ODSShort y = minY; y <= maxY; y += kGridSize)
- {
- MoveTo(minX,y);
- LineTo(maxX,y);
- }
-
- // Restore state
- RGBForeColor(&tColor);
- SetPenState(&tPen);
-
- ODReleaseObject(ev,frameShape);
- }
- //------------------------------------------------------------------------------
- // Method: DrawFrameView
- // Origin: DrawEditor
- //
- // Description: This method is called by the part when the frame being
- // drawn is in "frame" view.
- //
- // DrawEditor really has not intrisic content. However,
- // to provide some visual display, we draw the class name
- // at 80% of the frame's current height using an outlined
- // font.
- //------------------------------------------------------------------------------
-
- void DrawEditor::DrawFrameView( Environment* ev,
- ODFacet* facet,
- ODShape* invalidShape )
- {
- SOM_Trace("DrawEditor","DrawFrameView");
-
- ODFrame* frame;
- ODSLong savedRefNum = 0;
- CFrameInfo* frameInfo;
-
- // If the facet being draw is attached to a source frame in
- // another window, we need to access the source frame to determine
- // what size to draw the content.
- frameInfo = (CFrameInfo*) facet->GetFrame(ev)->GetPartInfo(ev);
- if ( frameInfo->HasSourceFrame() )
- frame = frameInfo->GetSourceFrame();
- else
- frame = facet->GetFrame(ev);
-
- // Clear the screen
- GrafPtr thePort;
- GetPort(&thePort);
- EraseRect(&thePort->portRect);
-
- // If the part is selected, fill the background with
- // the highlight color.
- if ( facet->GetHighlight(ev) == kODFullHighlight )
- {
- UInt8 mode = LMGetHiliteMode();
- BitClr(&mode,pHiliteBit);
- LMSetHiliteMode(mode);
- InvertRect(&thePort->portRect);
- }
-
- // Draw the grid
- DrawGrid(ev, frame);
-
- // Draw Content, if it falls within the invalid shape
- COrdListIterator iter(fShapeList);
- for (CShape* shape = (CShape*)iter.Last();
- iter.IsNotComplete();
- shape = (CShape*)iter.Previous())
- {
- ODShape* updateShape = invalidShape->Copy(ev);
-
- shape->GetUpdateShape(ev, updateShape);
-
- updateShape->Intersect(ev, invalidShape);
-
- if (!updateShape->IsEmpty(ev))
- {
- shape->DrawShape(ev, facet);
- }
-
- ODReleaseObject(ev, updateShape);
- }
- }
-
- //------------------------------------------------------------------------------
- // Method: DrawIconView
- // Origin: DrawEditor
- //
- // Description: This method is called by the part when the frame being
- // drawn is in "standard icon" view.
- //
- // The part uses the Icon Utilities toolbox manager to
- // aid in drawing icons in active windows. The Guidelines
- // require a different appearance for selected icons in
- // inactive windows, which we do manually.
- //------------------------------------------------------------------------------
-
- void DrawEditor::DrawIconView( Environment* ev,
- ODFacet* facet )
- {
- SOM_Trace("DrawEditor","DrawIconView");
-
- Rect iconRect;
- IconTransformType transformType = ttNone;
- CFrameInfo* frameInfo;
- ODFrame* frame;
- ODTypeToken viewType;
-
- frame = facet->GetFrame(ev);
- viewType = frame->GetViewType(ev);
- frameInfo = (CFrameInfo*) frame->GetPartInfo(ev);
-
- // Check to see if the facet is selected
- if ( facet->GetHighlight(ev) == kODFullHighlight )
- transformType = ttSelected;
-
- // Check to see if the frame has been opened into a part window.
- if ( frameInfo->HasPartWindow() &&
- frameInfo->GetPartWindow()->IsShown(ev) )
- transformType |= ttOpen;
-
- // Draw the icon.
- if ( viewType == gGlobals->fLargeIconView )
- SetRect(&iconRect, 0, 0, kODLargeIconSize, kODLargeIconSize);
- else // ( viewType == gGlobals->fSmallIconView )
- SetRect(&iconRect, 0, 0, kODSmallIconSize, kODSmallIconSize);
-
- CUsingLibraryResources res;
- PlotIconID(&iconRect, atAbsoluteCenter, transformType, kDocumentIcons);
- }
-
- //------------------------------------------------------------------------------
- // Method: DrawThumbnailView
- // Origin: DrawEditor
- //
- // Description: This method is called by the part when the frame being
- // drawn is in "thumbnail" view.
- //
- // The part uses a picture for its thumbnail view because
- // it has no intrinsic content. A picture resource is
- // probably not sufficient for parts with real content.
- //------------------------------------------------------------------------------
-
- void DrawEditor::DrawThumbnailView( Environment* ev,
- ODFacet* /*facet*/ )
- {
- SOM_Trace("DrawEditor","DrawThumbnailView");
-
- ::LoadThumbnail(ev, &gGlobals->fThumbnail);
-
- Rect bounds = (**(PicHandle) gGlobals->fThumbnail).picFrame;
-
- OffsetRect(&bounds, -bounds.left, -bounds.top);
- DrawPicture((PicHandle) gGlobals->fThumbnail, &bounds);
- }
-
- //------------------------------------------------------------------------------
- // Method: GeometryChanged
- // Origin: ODPart
- //
- // Description: This method is called when the ExternalTransform or
- // ClipShape of a facet on one this part's display frames
- // changes.
- //------------------------------------------------------------------------------
-
- void DrawEditor::GeometryChanged( Environment* ev,
- ODFacet* facet,
- ODBoolean clipShapeChanged,
- ODBoolean /*externalTransformChanged*/ )
- {
- SOM_Trace("DrawEditor","GeometryChanged");
-
- if ( clipShapeChanged )
- // Specifying kODNULL means to invalidate the clipShape (which was
- // calculated from the usedShape).
- facet->Invalidate(ev, kODNULL, kODNULL);
-
- // do I NEED this?
- // this->ClipEmbeddedFacets(ev, facet); // extra work, but gives correct display
- }
-
- //------------------------------------------------------------------------------
- // Method: HighlightChanged
- // Origin: ODPart
- //
- // Description: This method is called when a facet....
- //------------------------------------------------------------------------------
-
- void DrawEditor::HighlightChanged(Environment* ev, ODFacet* facet)
- {
- ODFrame* frame = facet->GetFrame(ev);
-
- // The frame view has no "special" drawing characteristics
- // when opened or selected, so we don't need to update our
- // content.
-
- if ( frame->GetViewType(ev) != gGlobals->fFrameView )
- frame->Invalidate(ev, kODNULL, kODNULL);
-
- // But we DO need to notify the embedded facets (if any) of the change
- ODFacetIterator* tIterator = facet->CreateFacetIterator(ev,
- kODChildrenOnly, kODFrontToBack);
- ODHighlight tHighlight = facet->GetHighlight(ev);
- for ( ODFacet* embeddedFacet = tIterator->First(ev);
- tIterator->IsNotComplete(ev);
- embeddedFacet = tIterator->Next(ev) )
- {
- ::ChangeFacetHighlight(ev, embeddedFacet, tHighlight);
- }
- }
-
- //------------------------------------------------------------------------------
- // Method: BeginRelinquishFocus
- // Origin: ODPart
- //
- // Description: This method is called when another part (or possibly
- // ourself) is requesting a focus for one of its display
- // frames. Returning true means we are willing to give
- // up the requested focus.
- //
- // The part willingly gives up any focus unless it is the
- // modal focus which we don't want to give up until we
- // are completely done displaying a modal dialog.
- //------------------------------------------------------------------------------
-
- ODBoolean DrawEditor::BeginRelinquishFocus( Environment* ev,
- ODTypeToken focus,
- ODFrame* /*ownerFrame*/,
- ODFrame* proposedFrame )
- {
- SOM_Trace("DrawEditor","BeginRelinquishFocus");
-
- ODBoolean willRelinquish = kODTrue;
-
- // If the frame that is requesting the selection focus is IN our selection
- // then close the current selection.
- if ( focus == gGlobals->fSelectionFocus )
- {
-
- // Is the proposed frame one of our embedded frames?
- // If so, is it selected?
- CShape* tShape = this->ShapeForFrame(ev, proposedFrame);
- if (tShape && tShape->IsSelected())
- {
- fSelection->CloseSelection(ev);
- }
- }
-
- // Another part is trying to put up a Modal dialog while we
- // are currently displaying ours. Deny the request.
- if ( focus == gGlobals->fModalFocus )
- {
- ODPart* proposedPart = proposedFrame->AcquirePart(ev);
- if ( ODObjectsAreEqual(ev, proposedPart, GetODPart()) == kODFalse )
- willRelinquish = kODFalse;
- ODReleaseObject(ev, proposedPart);
- }
-
- return willRelinquish;
- }
-
- //------------------------------------------------------------------------------
- // Method: CommitRelinquishFocus
- // Origin: ODPart
- //
- // Description: This method is called when it is actually time to give
- // up a focus that had been requested by another part (or
- // possibly ourself).
- //
- // The part calls its FocusLost method to handle the
- // "reliquishing" of the particular focus.
- //------------------------------------------------------------------------------
-
- void DrawEditor::CommitRelinquishFocus( Environment* ev,
- ODTypeToken focus,
- ODFrame* ownerFrame,
- ODFrame* /*proposedFrame*/ )
- {
- SOM_Trace("DrawEditor","CommitRelinquishFocus");
-
- // We agreed to give up our FocusSet and now we are being asked to
- // do so.
- this->FocusLost(ev, focus, ownerFrame);
- }
-
- //------------------------------------------------------------------------------
- // Method: AbortRelinquishFocus
- // Origin: ODPart
- //
- // Description: This method is called when another part (or possibly
- // ourself) requested a focus for one of its display
- // frames, but we returned kODFalse from
- // BeginRelinqishFocus for one, or all, of the requested
- // focus. At this point, we are being told to resume
- // ownership of the focus.
- //
- // The part calls its FocusAcquired method to handle the
- // re-"acquisition" of the particular focus.
- //------------------------------------------------------------------------------
-
- void DrawEditor::AbortRelinquishFocus( Environment* ev,
- ODTypeToken /*focus*/,
- ODFrame* /*ownerFrame*/,
- ODFrame* /*proposedFrame*/ )
- {
- SOM_Trace("DrawEditor","AbortRelinquishFocus");
-
- // Some parts may have suspended some events in the BeginRelinquishFocus
- // method. If so, they would resume those events here.
- }
-
- //------------------------------------------------------------------------------
- // Method: FocusAcquired
- // Origin: ODPart
- //
- // Description: This method is called when the Arbitrator has
- // registered us as the "owner" of the particular focus.
- // This can occur if a focus is requested, or if a focus
- // is transfered to one of the part's display frames.
- //
- // The part will display the menu bar when the menu focus
- // is acquired, and mark a frame active if the selection
- // focus is acquired.
- //------------------------------------------------------------------------------
-
- void DrawEditor::FocusAcquired( Environment* ev,
- ODTypeToken focus,
- ODFrame* ownerFrame )
- {
- SOM_Trace("DrawEditor","FocusAcquired");
-
- ODArbitrator* arbitrator = this->GetSession(ev)->GetArbitrator(ev);
-
- if ( focus == gGlobals->fMenuFocus )
- {
- if ( arbitrator->RequestFocus(ev, gGlobals->fSelectionFocus, ownerFrame))
- {
- this->PartActivated(ev, ownerFrame);
- }
- }
- else if ( focus == gGlobals->fSelectionFocus )
- {
- if ( arbitrator->RequestFocus(ev, gGlobals->fMenuFocus, ownerFrame) )
- {
- this->PartActivated(ev, ownerFrame);
- }
- }
- }
-
- //------------------------------------------------------------------------------
- // Method: FocusLost
- // Origin: ODPart
- //
- // Description: This method is called when the Arbitrator has
- // unregistered us as the "owner" of the particular
- // focus.
- //
- // The part unmarks the active frame if the selection
- // focus is lost.
- //------------------------------------------------------------------------------
-
- void DrawEditor::FocusLost( Environment* ev,
- ODTypeToken focus,
- ODFrame* ownerFrame )
- {
- SOM_Trace("DrawEditor","FocusLost");
-
- if ( focus == gGlobals->fSelectionFocus )
- {
- // Mark the frame as inactive
- CFrameInfo* frameInfo = (CFrameInfo*) ownerFrame->GetPartInfo(ev);
- frameInfo->SetFrameActive(kODFalse);
-
- // Only hide the palettes if a part other than "us" requested
- // the focus. This will prevent flash in the case where there
- // are multiple DrawEditors embedded inside a document.
- if (!gGlobals->fDrawEditorRequestingFocus)
- {
- // Hide our palettes
- if (gGlobals->fToolPalette->IsShown(ev))
- gGlobals->fToolPalette->ShowPalette(ev, kODFalse);
- if (gGlobals->fColorPalette->IsShown(ev))
- gGlobals->fColorPalette->ShowPalette(ev, kODFalse);
- }
-
- // Reset flag
- gGlobals->fDrawEditorRequestingFocus = kODFalse;
- }
- }
-
-
- //------------------------------------------------------------------------------
- // Method: RelinquishAllFoci
- // Origin: DrawEditor
- //
- // Description: This method relinquishes all foci for the given frame.
- //------------------------------------------------------------------------------
-
- void DrawEditor::RelinquishAllFoci(Environment* ev, ODFrame* frame)
- {
- ODArbitrator* arbitrator = GetODPart()->GetStorageUnit(ev)
- ->GetSession(ev)->GetArbitrator(ev);
-
- // Make sure the frame going away does not own any foci. Forgetting
- // to do this, will cause a "refcounting" error when the frame
- // is deleted by the draft.
-
- TRY
- TempODFrame focusFrame = arbitrator->AcquireFocusOwner(ev, gGlobals->fKeyFocus);
- if (focusFrame!=kODNULL)
- {
- if ( ODObjectsAreEqual(ev, focusFrame, frame) )
- {
- arbitrator->RelinquishFocus(ev, gGlobals->fKeyFocus, frame);
- this->FocusLost(ev, gGlobals->fKeyFocus, frame);
- }
- }
- CATCH_ALL
- ENDTRY
-
- TRY
- TempODFrame focusFrame = arbitrator->AcquireFocusOwner(ev, gGlobals->fClipboardFocus);
- if (focusFrame!=kODNULL)
- {
- if ( ODObjectsAreEqual(ev, focusFrame, frame) )
- {
- arbitrator->RelinquishFocus(ev, gGlobals->fClipboardFocus, frame);
- this->FocusLost(ev, gGlobals->fClipboardFocus, frame);
- }
- }
- CATCH_ALL
- ENDTRY
-
- TRY
- TempODFrame focusFrame = arbitrator->AcquireFocusOwner(ev, gGlobals->fSelectionFocus);
- if (focusFrame!=kODNULL)
- {
- if ( ODObjectsAreEqual(ev, focusFrame, frame) )
- {
- arbitrator->RelinquishFocus(ev, gGlobals->fSelectionFocus, frame);
- this->FocusLost(ev, gGlobals->fSelectionFocus, frame);
- }
- }
- CATCH_ALL
- ENDTRY
-
- TRY
- TempODFrame focusFrame = arbitrator->AcquireFocusOwner(ev, gGlobals->fMenuFocus);
- if (focusFrame!=kODNULL)
- {
- if ( ODObjectsAreEqual(ev, focusFrame, frame) )
- {
- arbitrator->RelinquishFocus(ev, gGlobals->fMenuFocus, frame);
- this->FocusLost(ev, gGlobals->fMenuFocus, frame);
- }
- }
- CATCH_ALL
- ENDTRY
- }
-
-
-
- //------------------------------------------------------------------------------
- // Method: PartActivated
- // Origin: DrawEditor
- //
- // Description: This method is called when the part has successfully acquired
- // the set of foci which allow it to "run".
- //------------------------------------------------------------------------------
-
- void DrawEditor::PartActivated( Environment* ev,
- ODFrame* frame )
- {
- SOM_Trace("DrawEditor","PartActivated");
-
- // We are required to re-validate the menubar before displaying it because
- // any part can/could swap the base menubar at any time.
- if ( gGlobals->fMenuBar->IsValid(ev) == kODFalse )
- {
- ODReleaseObject(ev, gGlobals->fMenuBar);
-
- ODMenuBar* tMenuBar = ODGetSession(ev,frame)->GetWindowState(ev)->CopyBaseMenuBar(ev);
-
- #ifdef ODDebug
- if (tMenuBar==kODNULL)
- DebugStr("\pCopyBaseMenuBar returned NULL menu bar!");
- #endif
-
- gGlobals->fMenuBar = tMenuBar;
-
- // After copying the "new" base menu bar, don't forget to re-install
- // your part's menus.
- this->LoadMenus(ev);
- }
-
- // Display our menu bar.
- gGlobals->fMenuBar->Display(ev);
-
- // And set our "active" state.
- CFrameInfo* frameInfo = (CFrameInfo*) frame->GetPartInfo(ev);
- frameInfo->SetFrameActive(kODTrue);
-
- // If we got the focus from some other part then are
- // palettes are hidded, show them.
- // Show our palettes
- if (gGlobals->fShowColorPalette)
- gGlobals->fColorPalette->ShowPalette(ev, kODTrue);
- if (gGlobals->fShowToolPalette)
- gGlobals->fToolPalette->ShowPalette(ev, kODTrue);
-
- // Reset flag, we are no longer requesting focus
- gGlobals->fDrawEditorRequestingFocus = kODFalse;
- }
-
-
- //------------------------------------------------------------------------------
- // Method: ActivateFrame
- // Origin: DrawEditor
- //
- // Description: This method is called by the part when a kODEvtMouseUp
- // occurs in an inactive frame in an active window, and
- // when an OpenDoc document comes forward.
- //
- // The part activates the frame by requesting the
- // UIFocusSet (created in Initialize) and by calling
- // FocusAcquired if we were successful. The method
- // returns true if no problems were encountered as a
- // signal to the caller that the frame is now "active".
- //------------------------------------------------------------------------------
-
- ODBoolean DrawEditor::ActivateFrame( Environment* ev,
- ODFrame* frame )
- {
- SOM_Trace("DrawEditor","ActivateFrame");
-
- // only activate frames that are in the main presentation
- ODTypeToken presentation = frame->GetPresentation(ev);
- if (presentation == gGlobals->fMainPresentation)
- {
- // Remember that we are requesting focus
- // So that if we already have the focus we
- // won't hide our palettes, thus preventing flash
- gGlobals->fDrawEditorRequestingFocus = kODTrue;
-
- // Request the set of foci necessary to become active.
- if ( this->GetSession(ev)->GetArbitrator(ev)->
- RequestFocusSet(ev, gGlobals->fUIFocusSet, frame))
- {
- this->PartActivated(ev, frame);
- }
- else
- // We were unable to acquire the foci we need to be active.
- return kODFalse;
- }
- else
- // Cannot activate frames not in the main presentation.
- return kODFalse;
-
- // We sucessfully acquired the foci we need to be active.
- return kODTrue;
- }
-
- //------------------------------------------------------------------------------
- // Method: WindowActivating
- // Origin: DrawEditor
- //
- // Description: This method is called by the part when a process
- // switch event (kODEvtOS) occurs.
- //
- // The part remembers the frame's active state and restores it when
- // events come in. If the frame is active and the window is being
- // sent into the background, remember to reactivate the part when
- // the window is reactivated.
- //------------------------------------------------------------------------------
-
- void DrawEditor::WindowActivating( Environment* ev,
- ODFrame* frame,
- ODBoolean activating )
- {
- SOM_Trace("DrawEditor","WindowActivating");
-
- CFrameInfo* frameInfo = (CFrameInfo*) frame->GetPartInfo(ev);
-
- // Check the presentation of the frame
- // Make sure it is the main presentation
- ODTypeToken presentation = frame->GetPresentation(ev);
- if (presentation == gGlobals->fMainPresentation)
- {
- ODBoolean checkPalettes = kODFalse;
-
- // The window is being activated and we had the selection focus when
- // the window was deactivated, so activate ourself.
- if ( activating && frameInfo->FrameNeedsReactivating() )
- {
- this->ActivateFrame(ev, frame);
- frameInfo->SetFrameReactivate(kODFalse);
- checkPalettes = kODTrue;
- }
- // The window is being deactivated and we have the active part.
- // So give up our foci and remind ourselves that we need to request
- // the focus when the window is reactivated.
- else if ( !activating && frameInfo->IsFrameActive() )
- {
- frameInfo->SetFrameReactivate(kODTrue);
- checkPalettes = kODTrue;
- }
-
- if ( checkPalettes )
- {
- // Show / Hide Palettes
- if (gGlobals->fShowToolPalette)
- gGlobals->fToolPalette->ShowPalette(ev, activating);
- if (gGlobals->fShowColorPalette)
- gGlobals->fColorPalette->ShowPalette(ev, activating);
- }
-
- // Must set hilite state of selected facets here
- fSelection->Activate(ev, activating, frame);
-
- if (!activating)
- {
- ODArbitrator* tArbitrator = this->GetSession(ev)->GetArbitrator(ev);
- TempODFrame clipboardFocus = tArbitrator->AcquireFocusOwner(ev, gGlobals->fClipboardFocus);
- if (ODObjectsAreEqual(ev, clipboardFocus, frame))
- tArbitrator->RelinquishFocus(ev, gGlobals->fClipboardFocus, frame);
- }
-
- }
-
- }
-
- //------------------------------------------------------------------------------
- // Method: ExecuteCommand
- // Origin: DrawEditor
- //
- // Description: This method is called when a command needs to be done for the first time.
- //
- //
- // Assumptions: This method assumes that if the command was not undoable that it may
- // be deleted after it is executed. Undo-able commands get registered with
- // OpenDoc and connot be deleted until they are committed.
- //------------------------------------------------------------------------------
-
- void DrawEditor::ExecuteCommand(Environment *ev, CCommand* command)
- {
- SOM_Trace("DrawEditor","ExecuteCommand");
-
- TRY
- command->DoCommand(ev); // execute the command
-
- if (!command->CanUndo()) // This command was not registered with OpenDoc.
- {
- command->Commit(ev, kODDone);
- delete command;
- }
- CATCH_ALL
- command->AbortCommand(ev);
- RERAISE;
- ENDTRY
- }
-
-
- //------------------------------------------------------------------------------
- // Method: UndoAction
- // Origin: ODPart
- //
- // Description: This method is called by OpenDoc when a command needs to be undone.
- //
- //
- //------------------------------------------------------------------------------
-
- void DrawEditor::UndoAction(Environment *ev, ODActionData* actionState)
- {
- SOM_Trace("DrawEditor","UndoAction");
-
- TRY
- CCommand* undoCommand = *((CCommand**)actionState->_buffer);
-
- if (undoCommand==kODNULL)
- return;
-
- undoCommand->UndoCommand(ev);
- CATCH_ALL
- ODSetSOMException(ev, kODErrUndefined);
- ENDTRY
- }
-
-
- //------------------------------------------------------------------------------
- // Method: RedoAction
- // Origin: ODPart
- //
- // Description: This method is called by OpenDoc when a command needs to be redone.
- //
- //
- //------------------------------------------------------------------------------
-
- void DrawEditor::RedoAction(Environment *ev, ODActionData* actionState)
- {
- SOM_Trace("DrawEditor","RedoAction");
-
- TRY
- CCommand* redoCommand = *((CCommand**)actionState->_buffer);
-
- // Better not be null!
- if (redoCommand==kODNULL)
- return;
-
- redoCommand->RedoCommand(ev);
- CATCH_ALL
- ODSetSOMException(ev, kODErrUndefined);
- ENDTRY
- }
-
-
- //------------------------------------------------------------------------------
- // Method: DisposeActionState
- // Origin: DrawEditor
- //
- // Description: This method is called by OpenDoc when an action has been
- // committed.
- //
- //
- //------------------------------------------------------------------------------
-
- void DrawEditor::DisposeActionState(Environment *ev,
- ODActionData* actionState,
- ODDoneState doneState)
- {
- SOM_Trace("DrawEditor","DisposeActionState");
-
- TRY
- CCommand* theCommand = *((CCommand**)actionState->_buffer);
-
- ODBoolean shouldDeleteCommand = kODTrue;
-
- // The command may be null, as in the case of a begin action.
- // See Command.h
- if (theCommand)
- {
- theCommand->Commit(ev, doneState);
-
- if (shouldDeleteCommand)
- delete theCommand;
- }
-
- CATCH_ALL
- ODSetSOMException(ev, kODErrUndefined);
- ENDTRY
- }
-
-
- //------------------------------------------------------------------------------
- // Method: HandleEvent
- // Origin: ODPart
- //
- // Description: The method is called when an event, which falls into
- // the category of an owned focus, occurs. The two
- // exceptions to this are "mouse movement" events and
- // embedded frame events, which can occur when a part
- // owns no foci.
- //
- // The part returns true if the event was handled.
- //------------------------------------------------------------------------------
-
- ODBoolean DrawEditor::HandleEvent( Environment* ev,
- ODEventData* event,
- ODFrame* frame,
- ODFacet* facet,
- ODEventInfo* eventInfo )
- {
- SOM_Trace("DrawEditor","HandleEvent");
-
- ODBoolean eventHandled = kODFalse;
-
- // Event handling is basically the same as standard Macintosh applications,
- // except that the events have been renamed for cross-platform compatability.
-
- switch ( event->what )
- {
- case kODEvtMouseDown:
- case kODEvtBGMouseDown :
- case kODEvtMouseUpBorder:
- case kODEvtMouseUp:
- case kODEvtMouseUpEmbedded:
- case kODEvtMouseDownEmbedded:
- case kODEvtBGMouseDownEmbedded :
- eventHandled = this->HandleMouseEvent(ev, event, facet, eventInfo);
- break;
-
- // Special case
- case kODEvtMouseDownBorder:
- eventHandled = HandleMouseDownInEmbeddedFrameBorder( ev, facet, event, eventInfo );
- break;
-
- case kODEvtMenu:
- eventHandled = this->HandleMenuEvent(ev, event, frame);
- break;
-
- case kODEvtActivate:
- // We are being notified that a window we are displayed in has
- // just been de/activated (un/hilighted).
- this->WindowActivating(ev, frame, (event->modifiers & activeFlag));
- eventHandled = kODTrue;
- break;
-
- case kODEvtMouseEnter:
- case kODEvtMouseLeave:
- SetCursor(&ODQDGlobals.arrow);
- eventHandled = kODTrue;
- break;
-
- case kODEvtMouseWithin:
- eventHandled = kODTrue;
- break;
-
- case kODEvtWindow:
- eventHandled = HandleWindowEvent(ev, event, frame);
- break;
-
- // Other events a part might handle
- case kODEvtNull:
- case kODEvtKeyDown:
- case kODEvtKeyUp:
- case kODEvtAutoKey:
- case kODEvtDisk:
- case kODEvtOS:
-
- default:
- break;
- }
-
- return eventHandled;
- }
-
- //------------------------------------------------------------------------------
- // Method: HandleMenuEvent
- // Origin: DrawEditor
- //
- // Description: This method is called by the part when a menu event is
- // received.
- //
- // Using the menu bar object, we determine what the menu
- // command is, and call the appropriate method to handle
- // it.
- //------------------------------------------------------------------------------
-
- ODBoolean DrawEditor::HandleMenuEvent( Environment* ev,
- ODEventData* event,
- ODFrame* frame )
- {
- SOM_Trace("DrawEditor","HandleMenuEvent");
-
- ODULong menuResult = event->message;
- ODUShort menu = HiWord(menuResult);
- ODUShort item = LoWord(menuResult);
-
- ODCommandID commandID = gGlobals->fMenuBar->GetCommand(ev, menu, item);
- switch (commandID)
- {
- case kODCommandAbout:
- this->DoDialogBox(ev, frame, kAboutBoxID);
- return kODTrue;
- break;
-
- case kODCommandViewAsWin:
- this->Open(ev, frame);
- return kODTrue;
- break;
-
- // Clipboard
- case kODCommandCopy:
- case kODCommandCut:
- return this->DoCutCopy(ev, commandID, frame);
- break;
-
- case kODCommandPaste: return this->DoPaste(ev, frame);
- break;
-
- case kODCommandPasteAs:
- {
- // Get any facet to pass to ShowPasteAsDlg
- TempODFrameFacetIterator facets(ev,frame);
- return this->DoPasteAs(ev, frame, facets.Current());
- }
- break;
-
- case kODCommandClear: return this->DoClear(ev, frame);
- break;
-
- case kODCommandSelectAll:
- fSelection->SelectAll(ev, frame);
- return kODTrue;
- break;
-
- // Drawing Commands
- case kMoveForwardCmd:
- case kMoveFrontCmd:
- case kMoveBackwardCmd:
- case kMoveBackCmd:
- CMoveShapeCommand* command = new CMoveShapeCommand( this,
- frame, commandID, fSelection);
- this->ExecuteCommand(ev, command);
- return kODTrue;
- break;
-
- case kShowHideToolPaletteCmd:
- gGlobals->fShowToolPalette = !gGlobals->fShowToolPalette;
- gGlobals->fToolPalette->ShowPalette( ev, gGlobals->fShowToolPalette);
- return kODTrue;
- break;
-
- case kShowHideColorPaletteCmd:
- gGlobals->fShowColorPalette = !gGlobals->fShowColorPalette;
- gGlobals->fColorPalette->ShowPalette( ev, gGlobals->fShowColorPalette);
- return kODTrue;
- break;
-
- // This command should only be active in the case where one
- // embedded shape is selected, or if a Link or Link source is selected.
- case kODCommandGetPartInfo:
- {
- if (fSelection->IsOneLink())
- {
- CPublishLink* pLink = (CPublishLink*)fSelection->GetPublishLinks()->First();
- if (pLink)
- pLink->ShowLinkInfoDialog(ev);
- else
- {
- CSubscribeLink* sLink = (CSubscribeLink*)fSelection->GetSubscribeLinks()->First();
- if (!sLink)
- {
- COrdListIterator iter(fSelection->GetShapeList());
- for (CShape* shape = (CShape*)iter.First();
- iter.IsNotComplete();
- shape = (CShape*)iter.Next())
- {
- if ((sLink = shape->GetSubscribeLink()) != kODNULL)
- break;
- }
- }
- ASSERT_NOT_NULL(sLink);
-
- sLink->ShowLinkInfoDialog(ev);
- }
- }
- else
- {
- // Selection should be just one embedded shape
- CEmbeddingShape* tShape = fSelection->IsOneEmbeddedShape(ev);
- THROW_IF_NULL(tShape);
-
- // We should always have at least one frame available
- // Actually, this could fail if the part is scrolled off screen
- // DCS $$$$$
- ODFrame* tFrame = tShape->GetAnyFrame(ev);
- THROW_IF_NULL(tFrame);
-
- // Get any facet to pass to ShowPartFrameInfo
- TempODFrameFacetIterator facets(ev,tFrame);
- ODInfo* info = this->GetSession(ev)->GetInfo(ev);
- info->ShowPartFrameInfo( ev,
- facets.Current(),
- !IsReadOnly());
- }
- return kODTrue;
- }
- break;
-
- case kODCommandOpen:
- this->DoOpen(ev, frame);
- return kODTrue;
- break;
-
- // Other commands a part might handle
- case kODCommandInsert:
- case kODCommandPageSetup:
- case kODCommandPrint:
- case kODCommandPreferences:
- break;
-
- }
-
- return kODFalse;
- }
-
- //------------------------------------------------------------------------------
- // Method: HandleMouseUpActivate
- // Origin: DrawEditor
- //
- // Description: This method is called by handlers which respond to mouse ups.
- // Here we will do the necessary work to activate the frame and window, if they
- // are not already active.
- //
- //
- // Remember: When a frame is inactive, the first mouse up event
- // should activate it; inactive frames do not recieve
- // kODEvtMouseDown events.
- //------------------------------------------------------------------------------
-
- ODBoolean DrawEditor::HandleMouseUpActivate( Environment* ev, ODFacet* facet)
- {
- ODWindow* window = facet->GetWindow(ev);
-
- TRY
- // Activate inactive windows on the first mouse up event.
- if ( !window->IsActive(ev) )
- window->Select(ev);
- // Activate the frame (if needed) on all subsequent mouse up events.
- else
- {
- ODFrame* frame = facet->GetFrame(ev);
-
- // Get our state information from the PartInfo of the frame.
- CFrameInfo* frameInfo = (CFrameInfo*) frame->GetPartInfo(ev);
-
- // If this frame is not the active one, activate it by requesting
- // the appropriate foci.
-
- if ( !frameInfo->IsFrameActive() )
- {
- if ( this->ActivateFrame(ev, frame) )
- {
- // Keep track of which facet was the last active for positioning
- // child windows.
- frameInfo->SetActiveFacet(facet);
- }
- else
- // We were unable to acquire the necessary focus and activate it.
- return kODFalse;
- }
- }
- CATCH_ALL
- return kODFalse;
- ENDTRY
-
- return kODTrue;
- }
-
-
- //------------------------------------------------------------------------------
- // Method: HandleMouseEvent
- // Origin: DrawEditor
- //
- // Description: This method is called by the part when a mouse event
- // is recieved.
- //
- // A typical part would determine the event type(up/down)
- // and respond appropriately, but we have no "real"
- // content model, so we activate the part as appropriate
- // and call a generic method to handle the event.
- //
- // Remember: When a frame is inactive, the first mouse up event
- // should activate it; inactive frames do not recieve
- // kODEvtMouseDown events.
- //------------------------------------------------------------------------------
-
- ODBoolean DrawEditor::HandleMouseEvent( Environment* ev,
- ODEventData* event,
- ODFacet* facet,
- ODEventInfo* eventInfo )
- {
- SOM_Trace("DrawEditor","HandleMouseEvent");
-
- if ( facet != kODNULL )
- {
- switch ( event->what)
- {
- case kODEvtMouseUp :
- case kODEvtMouseUpEmbedded:
- case kODEvtMouseUpBorder:
- this->HandleMouseUpActivate(ev, facet);
- return kODTrue;
- break;
-
- case kODEvtMouseDownEmbedded:
- case kODEvtBGMouseDownEmbedded :
- return HandleMouseDownInEmbeddedFrame( ev, facet, event, eventInfo );
- break;
-
- case kODEvtMouseDown :
- case kODEvtBGMouseDown :
- // Handle the mouse down event.
- this->HandleMouseDown(ev, facet, event, eventInfo);
- return kODTrue;
- break;
-
- case kODEvtMouseDownBorder:
- return HandleMouseDownInEmbeddedFrameBorder( ev, facet, event, eventInfo );
- return kODTrue;
- break;
-
- // Always handles event
- return kODTrue;
- default:
- return kODFalse;
- }
- }
- else
- {
- // User clicked outside the bounds of a Modal window.
-
- SysBeep(1);
- return kODTrue;
- }
-
- return kODFalse;
- }
-
- //------------------------------------------------------------------------------
- // Method: HandleWindowEvent
- // Origin: DrawEditor
- //
- // Description: This method is called by the part to handle window events.
- //------------------------------------------------------------------------------
-
- ODBoolean DrawEditor::HandleWindowEvent( Environment* ev,
- ODEventData* event,
- ODFrame* frame )
- {
- ODBoolean handled = kODFalse;
-
- switch ( event->message )
- {
- case inGoAway:
- // If the frame belonged to one of our palettes, then
- // change the show flag.
- ODTypeToken presentation = frame->GetPresentation(ev);
- if (presentation == gGlobals->fColorPalette->GetPresentation())
- {
- gGlobals->fShowColorPalette = kODFalse;
- }
- else
- if (presentation == gGlobals->fToolPalette->GetPresentation())
- {
- gGlobals->fShowToolPalette = kODFalse;
- }
- break;
-
- default: ;
- }
-
- return handled;
- }
-
- //------------------------------------------------------------------------------
- // Method: HandleSelection
- // Origin: DrawEditor
- //
- // Description: This method is called by HandleMouseDown to handle selection with
- // the mouse.
- //------------------------------------------------------------------------------
-
- ODBoolean DrawEditor::HandleSelection( Environment* ev,
- ODFacet* facet,
- ODEventData* event,
- ODEventInfo* eventInfo)
- {
- // Get the localized mouse coordinates from the Event Info.
- Point where;
- where.h = FixedToInt(eventInfo->where.x);
- where.v = FixedToInt(eventInfo->where.y);
-
- // Did the user click in a shape handle?
- short whichHandle;
- CShape* shape = fSelection->WhichHandle(ev, facet, where, &whichHandle);
- if (shape != kODNULL)
- {
- if (this->IsReadOnly())
- {
- SysBeep(1);
- return kODTrue;
- }
-
- CSubscribeLink* link = kODNULL;
- if (fLinkStatus == kODInLinkDestination || !fSelection->CanEditSelectedContent(link))
- this->EditInLink(ev, link);
-
- // We havn't tracked the drag, so can't complete the users action if the link was broken
- // in response to the dialog
- else
- fSelection->Resize(ev, shape, facet, whichHandle, event);
-
- return kODTrue;
- }
-
- // if not in a handle, look for a shape
- shape = this->WhichShape(ev, where);
-
- // If the user did not click in a shape then we must begin tracking a selection
- // and select some shapes. There is code in the selection class to do this.
- if (shape == kODNULL)
- {
- // Have the selection track the mouse and ( possibly ) select shapes.
- fSelection->SelectWithRectangle(ev, facet, event);
-
- // Must call our activate code here since the lasso consumes the mouse
- // up event.
- this->HandleMouseUpActivate(ev, facet);
- }
- else
- {
- // The user clicked in a shape. Either extend or change the selection.
- // Again, the selection class has code for modifying the selection in
- // this case.
- fSelection->SelectWithShape(ev, facet, event, shape);
- }
-
- return kODTrue;
- }
-
- //------------------------------------------------------------------------------
- // Method: DropCompleted
- // Origin: ODPart
- //
- // Description: This method may be called by OpenDoc when an asynchronous
- // drop is completed. I also call this method from my DropShape command to
- // turn off drag hiliting.
- //------------------------------------------------------------------------------
-
- void DrawEditor::DropCompleted(Environment *ev, ODPart* part, ODDropResult result)
- {
- // If drag hiliting is on turn it off
- if (fHilightedDragFacet)
- {
- HiliteFacet(ev, this->GetSession(ev)->GetDragAndDrop(ev), fHilightedDragFacet, kODFalse);
- fHilightedDragFacet = kODNULL;
- }
- }
-
-
- //------------------------------------------------------------------------------
- // Method: DragEnter
- // Origin: ODPart
- //
- // Description: Track the drag. The part should display a drag target border within
- // the facet. During drag tracking (DragEnter, DragWithin) the part should
- // never attempt to read data from any of the storage units supplied
- // by the iterator. The part should only inspect the type of
- // the dragged data.
- //
- // If the part can accept a drop, it should return
- // kODTrue. Otherwise, it should return kODFalse.
- //------------------------------------------------------------------------------
-
- ODDragResult DrawEditor::DragEnter(Environment *ev,
- ODDragItemIterator* dragInfo,
- ODFacet* facet,
- ODPoint* where)
- {
- // Do not accept drags if this draft is marked read only
- if (this->IsReadOnly())
- return kODFalse;
-
- // Do not accept drags if we are in low memory conditions
- TRY
- // Will throw if in low mem
- ::ODCheckAppHeapSpace();
- CATCH_ALL
- DebugStr("\pLo mem in drag enter.");
- return kODFalse;
- ENDTRY
-
- // We can accept anything
-
- // Highlight the facet if the drag has ( ever ) left the source frame.
- ODDragAndDrop* drag = this->GetSession(ev)->GetDragAndDrop(ev);
- ODULong attributes = drag->GetDragAttributes(ev);
- ODBoolean dragIsInSourceFrame = attributes & kODDragIsInSourceFrame;
-
- if (!dragIsInSourceFrame)
- {
- HiliteFacet(ev, GetSession(ev)->GetDragAndDrop(ev), facet, kODTrue);
- fHilightedDragFacet = facet;
- }
-
- return kODTrue;
- }
-
-
- //------------------------------------------------------------------------------
- // Method: DragLeave
- // Origin: ODPart
- //
- // Description: This method is called by OpenDoc when a drag occurs within
- // a facet.
- //------------------------------------------------------------------------------
-
- void DrawEditor::DragLeave(Environment *ev,
- ODFacet* facet,
- ODPoint* where)
- {
- if (fHilightedDragFacet)
- {
- HiliteFacet(ev, GetSession(ev)->GetDragAndDrop(ev), facet, kODFalse);
- fHilightedDragFacet = kODNULL;
- }
-
- }
-
-
- //------------------------------------------------------------------------------
- // Method: DragWithin
- // Origin: ODPart
- //
- // Description: This method is called by OpenDoc when a drag occurs within
- // a facet.
- //------------------------------------------------------------------------------
-
- ODDragResult DrawEditor::DragWithin(Environment *ev,
- ODDragItemIterator* dragInfo,
- ODFacet* facet,
- ODPoint* where)
- {
- return kODTrue;
- }
-
-
- //------------------------------------------------------------------------------
- // Method: Drop
- // Origin: ODPart
- //
- // Description: This method is called by OpenDoc when a drop occurs.
- //------------------------------------------------------------------------------
-
- ODDropResult DrawEditor::Drop(Environment *ev,
- ODDragItemIterator* dragInfo,
- ODFacet* facet,
- ODPoint* where)
- {
- ODDropResult dropResult = kODDropFail;
-
- // ----- 'where' is in frame coordinate. Put it in content coordinate
- ODPoint dropPoint = *where;
- ODFrame* tFrame = facet->GetFrame(ev);
- ODTransform* frameTrans = tFrame->AcquireInternalTransform(ev, kODNULL);
- frameTrans->InvertPoint(ev, &dropPoint); // Drop point is modified in place
- ODReleaseObject(ev,frameTrans);
-
- // we need first to check the drag attributes and show a paste as dialog if so indicated
- // It would be nice to factor some common code from here and from DoPasteAs (for the menu choice)
- // but there are several little differences that make it a nuisance to do so.
-
- ODBoolean usePAResult = kODFalse;
- ODStorageUnit* dropSU = dragInfo->First(ev);
- ODBoolean canMerge = dropSU->Exists(ev, kODPropContents, kDrawEditorKind, 0);
- ODBoolean canEmbedSingleFrame = dropSU->Exists(ev, kODPropContentFrame, kODWeakStorageUnitRef, 0);
- ODPasteAsMergeSetting mergeSetting;
- ODPasteAsResult paResult;
-
- if (canMerge)
- {
- if (canEmbedSingleFrame)
- mergeSetting = kODPasteAsEmbed;
- else
- mergeSetting = kODPasteAsMerge;
- }
- else
- mergeSetting = kODPasteAsEmbedOnly;
-
- ODSession* session = this->GetSession(ev);
- ODDragAndDrop* drag = session->GetDragAndDrop(ev);
- ODULong attributes = drag->GetDragAttributes(ev);
-
- CDropShapeCommand* dropCommand = kODNULL;
- if (attributes & kODDropIsPasteAs)
- {
-
- usePAResult = drag->ShowPasteAsDialog(ev, kODTrue, mergeSetting,
- facet, // facet from which dialog is triggered
- session->Tokenize(ev, kODViewAsFrame), // viewType of data
- dropSU, &paResult);
- if (usePAResult)
- {
- TRY
- ODBoolean doLink = paResult.pasteLinkSetting == kODTrue;
-
- if (doLink)
- {
- ODBoolean defaultIsMerge = (mergeSetting == kODPasteAsMerge);
- CDropLinkCommand* command = new CDropLinkCommand(this, fSelection, dropSU, dropPoint, paResult, defaultIsMerge);
- this->ExecuteCommand(ev, command);
- dropResult = kODDropCopy;
- }
- else
- {
- ODBoolean doMerge = canMerge && paResult.mergeSetting;
-
- // determine embed vs merge choice from paResult.
- dropCommand = new CDropAsCommand(this, facet, dragInfo, fSelection, dropPoint, !doMerge);
- this->ExecuteCommand(ev, dropCommand);
-
- // Remember the drop result
- dropResult = dropCommand->GetDropResult();
- }
-
- CATCH_ALL
- dropResult = kODDropFail;
- ENDTRY
- }
- else
- {
- // User cancelled.
-
- // Turn off drag highlight
- if (fHilightedDragFacet)
- {
- HiliteFacet(ev, GetSession(ev)->GetDragAndDrop(ev), facet, kODFalse);
- fHilightedDragFacet = kODNULL;
- }
-
- // Fail the drop
- dropResult = kODDropFail;
- }
-
- // Dispose of pasteAsResult fields
- ODDisposePtr(paResult.selectedKind);
- ODDisposePtr(paResult.translateKind);
- ODDisposePtr(paResult.editor);
- }
- else
- {
- dropCommand = new CDropShapeCommand(this, facet, dragInfo, fSelection, dropPoint, kODTrue);
-
- // This should be safe to do since D&D is undoable, the command won't be deleted
- // right away. So, we can query the drop result in the next block.
- this->ExecuteCommand(ev, dropCommand);
-
- // Remember the drop result
- dropResult = dropCommand->GetDropResult();
- }
-
- return dropResult;
- }
-
-
- //------------------------------------------------------------------------------
- // Method: HandleMouseDownInEmbeddedFrame
- // Origin: DrawEditor
- //
- // Description: This method is called by the part to handle mouse down
- // events that occur in embedded frames.
- //
- //------------------------------------------------------------------------------
-
- ODBoolean DrawEditor::HandleMouseDownInEmbeddedFrame( Environment* ev,
- ODFacet* facet,
- ODEventData* event,
- ODEventInfo* eventInfo )
- {
-
- // Check the embedded frame parameter
- ODFrame* embeddedFrame = eventInfo->embeddedFrame;
- if (embeddedFrame==kODNULL)
- return kODFalse;
-
- // Get the shape for the frame clicked on, check that it's valid
- CShape* tShape = this->ShapeForFrame(ev, eventInfo->embeddedFrame);
- if (tShape==kODNULL)
- return kODFalse;
-
- fSelection->SelectWithShape(ev, facet, event, tShape);
- return kODTrue;
- }
-
-
- //------------------------------------------------------------------------------
- // Method: HandleMouseDownInEmbeddedFrameBorder
- // Origin: DrawEditor
- //
- // Description: This method is called by the part to handle mouse down
- // events that occur in embedded frame borders.
- //
- //------------------------------------------------------------------------------
-
- ODBoolean DrawEditor::HandleMouseDownInEmbeddedFrameBorder( Environment* ev,
- ODFacet* facet,
- ODEventData* event,
- ODEventInfo* eventInfo )
- {
- // Check the embedded frame parameter
- ODFrame* embeddedFrame = eventInfo->embeddedFrame;
- if (embeddedFrame==kODNULL)
- return kODFalse;
-
- // Get the shape for the frame clicked on, check that its valid
- CShape* tShape = this->ShapeForFrame(ev, eventInfo->embeddedFrame);
- if (tShape==kODNULL)
- return kODFalse;
-
- fSelection->SelectWithShape(ev, facet, event, tShape);
-
- return kODTrue;
- }
-
-
- //------------------------------------------------------------------------------
- // Method: HandleMouseDown
- // Origin: DrawEditor
- //
- // Description: This method is called by the part to handle mouse
- // events.
- //------------------------------------------------------------------------------
-
- void DrawEditor::HandleMouseDown( Environment* ev,
- ODFacet* facet,
- ODEventData* event,
- ODEventInfo* eventInfo )
- {
- SOM_Trace("DrawEditor","HandleMouseDown");
-
- // Get the window
- ODWindow* window = facet->GetWindow(ev);
-
- // Get the localized mouse coordinates from the Event Info.
- Point where;
- where.h = FixedToInt(eventInfo->where.x);
- where.v = FixedToInt(eventInfo->where.y);
-
- // Don't handle mouse downs in inactive windows, unless the mousedown is in
- // a shape.
- CShape* shape = this->WhichShape(ev, where);
-
- if ( !window->IsActive(ev)&&!shape)
- {
- window->Select(ev);
- return;
- }
-
-
- // HandleMouseDowns in Palettes
- ODTypeToken presentation = facet->GetFrame(ev)->GetPresentation(ev);
- if (presentation == gGlobals->fColorPalette->GetPresentation())
- {
- ODSShort paletteItem;
- ODBoolean selectionIsEmpty = fSelection->IsEmpty();
- if(gGlobals->fColorPalette->DoMouseDownInPalette(ev, facet->GetFrame(ev),
- where, &paletteItem, selectionIsEmpty))
- {
- if (!this->IsReadOnly())
- {
-
- // Can't change color of link destination content.
- CSubscribeLink* link = kODNULL;
- if (fLinkStatus == kODInLinkDestination || !fSelection->CanEditSelectedContent(link))
- this->EditInLink(ev, link);
-
- // if the user chose to break the link, then the status may have changed
- // so check again.
-
- if (fLinkStatus != kODInLinkDestination && fSelection->CanEditSelectedContent())
- {
- CRGBColor color;
- gGlobals->fColorPalette->GetColor(paletteItem, &color);
-
- CColorSelectionCommand* command =
- new CColorSelectionCommand(this, fSelection, color);
-
- this->ExecuteCommand(ev, command);
- }
- }
- }
- }
- else
- if (presentation == gGlobals->fToolPalette->GetPresentation())
- gGlobals->fToolPalette->DoMouseDownInPalette(ev, facet->GetFrame(ev), where);
- else
- if (presentation == gGlobals->fMainPresentation)
- {
- // Get the current tool
- ODSShort currentTool = gGlobals->fToolPalette->GetSelectedPaletteItem();
-
- switch (currentTool)
- {
- case kSelectionTool:
- // Try to select something
- this->HandleSelection(ev, facet, event, eventInfo);
- break;
-
- case kLineShapeTool:
- // Create a line shape.
- break;
-
- case kOvalTool:
- case kPolygonTool:
- case kRectangleTool:
- case kTextTool:
-
- CFocus draw(ev, facet);
-
- // Get rectangle
- Rect shapeRect;
- CRGBColor shapeColor;
- gGlobals->fColorPalette->GetColor(gGlobals->fColorPalette->GetSelectedPaletteItem(), &shapeColor);
-
- fSelection->TrackRectangle(ev, event, &shapeRect);
-
- // Do not create a shape if the rectangle is too small or invalid
- if (::RectContainsRect(shapeRect, gGlobals->fMinShapeSizeRect) || !::IsValidRect(shapeRect))
- {
- fSelection->CloseSelection(ev);
- return;
- }
-
- // Create the new shape command and execute it.
- CNewShapeCommand* command = new CNewShapeCommand(this, facet, shapeRect, shapeColor,
- currentTool,fSelection);
- this->ExecuteCommand(ev, command);
- break;
- }
- }
- }
-
-
- //------------------------------------------------------------------------------
- // Method: DoOpen
- // Origin: DrawEditor
- //
- // Description: Open all selected embedded parts into windows.
- //------------------------------------------------------------------------------
-
- void DrawEditor::DoOpen(Environment* ev, ODFrame* frame)
- {
- COrdListIterator iter(fSelection->GetShapeList());
-
- for ( CShape* shape = (CShape*)iter.First();
- iter.IsNotComplete();
- shape = (CShape*)iter.Next() )
- {
- shape->Open(ev, frame);
- }
-
- }
-
-
- //------------------------------------------------------------------------------
- // Method: DoClear
- // Origin: DrawEditor
- //
- // Description: This method is called by HandleMenuEvent to clear the current
- // selection.
- //------------------------------------------------------------------------------
-
- ODBoolean DrawEditor::DoClear(Environment* ev, ODFrame* frame)
- {
- CCutCopyClearShapeCommand* command = new CCutCopyClearShapeCommand(this,
- frame, fSelection,
- kODCommandClear);
-
- this->ExecuteCommand(ev, command);
- return kODTrue;
- }
-
-
- //------------------------------------------------------------------------------
- // Method: DoPasteAs
- // Origin: DrawEditor
- //
- // Description: This method is called by HandleMenuEvent to paste the contents
- // of the clipboard to the document. Embed Vs. Incorporate and Linking are dealt
- // with here as well.
- //------------------------------------------------------------------------------
-
- ODBoolean DrawEditor::DoPasteAs(Environment* ev, ODFrame* frame, ODFacet* facet)
- {
- // Get the clipboard storage unit and internalize it
- ODClipboard* clip = this->GetSession(ev)->GetClipboard(ev);
-
- // Get the clipboard content storage unit
- ODStorageUnit* contentSU = clip->GetContentStorageUnit(ev);
-
- ASSERT_NOT_NULL(contentSU->Exists(ev, kODPropContents, kODNULL, 0));
-
- ODBoolean result;
- ODBoolean canMerge = contentSU->Exists(ev, kODPropContents, kDrawEditorKind, 0);
- ODBoolean canEmbedSingleFrame = contentSU->Exists(ev, kODPropContentFrame, kODWeakStorageUnitRef, 0);
- ODPasteAsMergeSetting mergeSetting;
- ODPasteAsResult paResult;
-
- if (canMerge)
- {
- if (canEmbedSingleFrame)
- mergeSetting = kODPasteAsEmbed;
- else
- mergeSetting = kODPasteAsMerge;
- }
- else
- mergeSetting = kODPasteAsEmbedOnly;
-
- // ---- Display the Paste As... dialog ----
- result = clip->ShowPasteAsDialog(ev, kODTrue, mergeSetting,
- facet, // facet from which dialog is triggered
- gGlobals->fFrameView, // viewType of data
- &paResult);
- if (result)
- {
- TRY
- ODBoolean doLink = paResult.pasteLinkSetting == kODTrue;
-
- if (doLink)
- {
- ODBoolean defaultIsMerge = (mergeSetting == kODPasteAsMerge);
- CPasteLinkCommand* command = new CPasteLinkCommand(this, fSelection, contentSU, paResult, defaultIsMerge);
- this->ExecuteCommand(ev, command);
- }
- else
- {
- // Since this part only supports 1 kind, we can ignore that translation
- // result portion of paResult. The paste as command will do the right
- // thing in the native kind case. We need to worry about the force
- // embed case.
- CPasteAsCommand* command = new CPasteAsCommand(this, frame, fSelection, !paResult.mergeSetting);
- this->ExecuteCommand(ev, command);
- }
- CATCH_ALL
- // ExecuteCommand sahould clean up command
-
- // Dispose of pasteAsResult fields
- ODDisposePtr(paResult.selectedKind);
- ODDisposePtr(paResult.translateKind);
- ODDisposePtr(paResult.editor);
-
- RERAISE;
- ENDTRY
- }
-
- // Dispose of pasteAsResult fields
- ODDisposePtr(paResult.selectedKind);
- ODDisposePtr(paResult.translateKind);
- ODDisposePtr(paResult.editor);
-
-
- return kODTrue;
- }
-
-
- //------------------------------------------------------------------------------
- // Method: DoPaste
- // Origin: DrawEditor
- //
- // Description: This method is called by HandleMenuEvent to paste the contents
- // of the clipboard to the document.
- //------------------------------------------------------------------------------
-
- ODBoolean DrawEditor::DoPaste(Environment* ev, ODFrame* frame)
- {
- CPasteCommand* command = new CPasteCommand(this, frame, fSelection);
- this->ExecuteCommand(ev, command);
-
- return kODTrue;
- }
-
-
- //------------------------------------------------------------------------------
- // Method: DoCutCopy
- // Origin: DrawEditor
- //
- // Description: This method is called by HandleMenuEvent to cut/copy the current
- // selection to the clipboard.
- //------------------------------------------------------------------------------
-
- ODBoolean DrawEditor::DoCutCopy(Environment* ev,
- ODCommandID commandID,
- ODFrame* frame)
- {
- CCutCopyClearShapeCommand* command = new CCutCopyClearShapeCommand(this,
- frame,
- fSelection,
- commandID);
- this->ExecuteCommand(ev, command);
- return kODTrue;
- }
-
-
- //------------------------------------------------------------------------------
- // Method: EmbeddedFrameUpdated
- // Origin: ODPart
- //
- // Description: This method makes OpenDoc calls necessary before a dialog is
- // displayed. This method returns false if it can't successfully prepare
- // ( i.e can't get modal focus ).
- //------------------------------------------------------------------------------
-
- void DrawEditor::EmbeddedFrameUpdated( Environment* ev,
- ODFrame* frame, ODUpdateID updateID )
- {
- CShape* shape = this->ShapeForFrame(ev, frame);
-
- ASSERT_NOT_NULL(shape);
-
- COrdListIterator iter(shape->GetPublishLinks());
- for (CPublishLink* link = (CPublishLink*)iter.First(); iter.IsNotComplete(); link = (CPublishLink*)iter.Next())
- {
- link->ContentUpdated(ev, updateID);
- }
-
- return;
- }
-
-
- //------------------------------------------------------------------------------
- // Method: PrepareForDialog
- // Origin: DrawEditor
- //
- // Description: This method makes OpenDoc calls necessary before a dialog is displayed.
- // This method returns false if it can't successfully prepare ( i.e can't get modal focus ).
- //------------------------------------------------------------------------------
-
- ODBoolean DrawEditor::PrepareForDialog( Environment* ev, ODFrame* frame )
- {
- SOM_Trace("DrawEditor","PrepareForDialog");
-
- ODSession* session = GetODPart()->GetStorageUnit(ev)->GetSession(ev);
-
- // Our About box is modal so we must request the Modal focus to prevent
- // multiple modal dialogs being displayed simultaneously.
-
- if ( session->GetArbitrator(ev)->RequestFocus(ev, gGlobals->fModalFocus, frame) )
- {
- TRY
- // Dim the frontmost document window.
- session->GetWindowState(ev)->DeactivateFrontWindows(ev);
- return kODTrue;
- CATCH_ALL
- session->GetArbitrator(ev)->RelinquishFocus(ev, gGlobals->fModalFocus, frame);
- RERAISE;
- ENDTRY
- }
-
- return kODFalse;
- }
-
- //------------------------------------------------------------------------------
- // Method: DoneWithDialog
- // Origin: DrawEditor
- //
- // Description: This method makes OpenDoc calls necessary when a dialog is closed.
- //------------------------------------------------------------------------------
-
- void DrawEditor::DoneWithDialog( Environment* ev, ODFrame* frame )
- {
- SOM_Trace("DrawEditor","DoneWithDialog");
-
- ODSession* session = GetODPart()->GetStorageUnit(ev)->GetSession(ev);
-
- // Inform the Arbitrator that we no longer require the Modal focus.
- session->GetArbitrator(ev)->RelinquishFocus(ev, gGlobals->fModalFocus, frame);
-
- // Hilite the frontmost document window.
- session->GetWindowState(ev)->ActivateFrontWindows(ev);
- }
-
- //------------------------------------------------------------------------------
- // Method: DoDialogBox
- // Origin: DrawEditor
- //
- // Description: This method is called by the part when a dialog needs to be
- // displayed (ie. the About Box). If a valid error number is passed
- // in, an error dialog will be displayed.
- //------------------------------------------------------------------------------
-
- void DrawEditor::DoDialogBox( Environment* ev,
- ODFrame* frame,
- ODSShort dialogID,
- ODUShort errorNumber )
- {
- SOM_Trace("DrawEditor","DoDialogBox");
-
- ODFrame* focusFrame = frame;
- ODSession* session = ODGetSession(ev,fSelf);
-
- // If the calling method does not have a frame available to it, we need to
- // locate a frame to use for requesting the modal focus. Find the first valid
- // frame in our display frames list.
- if ( focusFrame == kODNULL )
- {
- COrdListIterator fiter(fDisplayFrameProxies);
- for ( CDisplayFrameProxy* frameProxy = (CDisplayFrameProxy*)fiter.First();
- fiter.IsNotComplete();
- frameProxy = (CDisplayFrameProxy*)fiter.Next())
- {
- // shouldn't get called to remove a frame that has
- // not yet been internalized
- if (frameProxy->IsFrameInMemory())
- {
- if (frameProxy->GetFrame(ev))
- {
- focusFrame = frameProxy->GetFrame(ev);
- }
- }
- }
- }
-
- // Our dialog boxes are modal so we must request the Modal focus to prevent
- // multiple modal dialogs being displayed simultaneously.
-
- if ( this->PrepareForDialog(ev, frame) )
- {
- DialogPtr dialog;
- ODSShort itemHit;
-
- ODSLong rfRef;
- rfRef = BeginUsingLibraryResources();
- {
- dialog = GetNewDialog(dialogID, kODNULL, (WindowPtr) -1L);
-
- if ( dialog )
- {
- if ( errorNumber > 0 )
- {
- Handle itemHandle;
- Rect itemRect;
- short itemType;
- Str255 errStr;
-
- GetIndString(errStr, kErrorStringResID, errorNumber);
- GetDialogItem(dialog, kErrStrFieldID, &itemType, &itemHandle, &itemRect);
- SetDialogItemText(itemHandle, errStr);
-
- // We don't need the cancel button for an error dialog.
- HideDialogItem(dialog, cancel);
-
- SetDialogDefaultItem(dialog, ok);
- }
-
- SetCursor(&ODQDGlobals.arrow);
- ShowWindow(dialog);
- ModalDialog(kODNULL, &itemHit);
- DisposeDialog(dialog);
- }
- else
- {
- // Could not load About box dialog... something is amiss.
- SysBeep(2);
- }
- }
- EndUsingLibraryResources(rfRef);
-
- this->DoneWithDialog(ev, frame);
- }
- else
- // If we can't get the modal focus, then another modal dialog is
- // already being displayed.
- SysBeep(2);
- }
-
-
-
- //------------------------------------------------------------------------------
- // Method: MoveShapeBefore
- // Origin: DrawEditor
- //
- // Description: This method moves the given shape before the 'before' shape
- // in our content shape list. It then calls the shape method MoveBefore.
- //------------------------------------------------------------------------------
- void DrawEditor::MoveShapeBefore(Environment* ev, CShape* moveShape, CShape* before)
- {
- // Don't try to remove if either shape is null
- if (moveShape==kODNULL || before==kODNULL)
- return;
-
- // Also, don't try to do anything if the shapes are the same
- if (before==moveShape)
- return;
-
- fShapeList->Remove(moveShape);
- fShapeList->AddBefore(before, moveShape);
-
- moveShape->MoveBefore(ev, before);
- }
-
-
- //------------------------------------------------------------------------------
- // Method: MoveShapeAfter
- // Origin: DrawEditor
- //
- // Description: This method moves the given shape after the 'after' shape
- // in our content shape list. It then calls the shape method MovedAfter.
- //------------------------------------------------------------------------------
- void DrawEditor::MoveShapeAfter(Environment* ev, CShape* moveShape, CShape* after)
- {
- // Don't try to remove if either shape is null
- if (moveShape==kODNULL || after==kODNULL)
- return;
-
- // Also, don't try to do anything if the shapes are the same
- if (after==moveShape)
- return;
-
- fShapeList->Remove(moveShape);
- fShapeList->AddAfter(after, moveShape);
-
- moveShape->MoveAfter(ev, after);
- }
-
-
- //------------------------------------------------------------------------------
- // Method: ShapeForFrame
- // Origin: DrawEditor
- //
- // Description: This method should return the embedding shape that is representing
- // the given embedded frame.
- //
- // This method should be used primarily for event handlers which get passed
- // that the user is manipulating.
- //------------------------------------------------------------------------------
-
- CShape* DrawEditor::ShapeForFrame(Environment* ev, ODFrame* embeddedFrame)
- {
- COrdListIterator iter(fShapeList);
- for (CShape* shape = (CShape*)iter.First(); iter.IsNotComplete(); shape = (CShape*)iter.Next())
- {
- ODBoolean itsThere = shape->ContainsProxyForFrame(ev, embeddedFrame);
- if (itsThere)
- return shape;
- }
-
- return kODNULL;
- }
-
- //------------------------------------------------------------------------------
- // Method: InvalidateShape
- // Origin: DrawEditor
- //
- // Description: This method causes the given Shapes area to be redrawn.
- //------------------------------------------------------------------------------
-
- void DrawEditor::InvalidateShape(Environment* ev, CShape* shape)
- {
- TRY
- COrderedList* contentFrames = this->GetContentDisplayFrames(ev);
- if (contentFrames)
- {
-
- // If we have any display frames..
- if (contentFrames->Count()>0)
- {
- // Then iterate over our them
- COrdListIterator iter(contentFrames);
-
- // Create a tempory shape to use to invalidate the CShape
- ODShape* tShape = ((ODFrame*)iter.First())->CreateShape(ev);
- shape->GetUpdateShape(ev, tShape);
-
- // invalidate the shapes area in all of our content frames
- for ( ODFrame* frame = (ODFrame*)iter.First();
- iter.IsNotComplete();
- frame = (ODFrame*)iter.Next() )
- {
- frame->Invalidate(ev, tShape, kODNULL);
- }
-
- // Release acquired geometry
- ODReleaseObject(ev,tShape);
- }
- }
-
-
- // Delete temp list
- delete contentFrames;
- CATCH_ALL
- ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // Method: AddShape
- // Origin: DrawEditor
- //
- // Description: This method adds the given shape to our list.
- //------------------------------------------------------------------------------
-
- void DrawEditor::AddShape(Environment* ev, CShape* shape)
- {
- fShapeList->AddFirst(shape);
-
- // If shape is visible, invalidate
- this->InvalidateShape(ev, shape);
-
- shape->Added(ev);
- }
-
- //------------------------------------------------------------------------------
- // Method: RemoveShape
- // Origin: DrawEditor
- //
- // Description: This method removes the given shape from our list and temporarily
- // removes it from the document ( if it is an embedded shape ).
- //------------------------------------------------------------------------------
-
- void DrawEditor::RemoveShape(Environment* ev, CShape* shape)
- {
- fShapeList->Remove(shape);
- this->InvalidateShape(ev, shape);
- shape->Removed(ev, kDontCommit);
- }
-
-
- //-----------------------------------------------------------------------------
- // DrawEditor::WhichShape
- // Origin: DrawEditor
- //-----------------------------------------------------------------------------
-
- CShape* DrawEditor::WhichShape(Environment *ev, Point& where)
- {
- COrdListIterator iter(fShapeList);
- for (CShape* shape = (CShape*)iter.First(); iter.IsNotComplete(); shape = (CShape*)iter.Next())
- {
- if (shape->HitTest(ev, where))
- return shape;
- }
-
- return kODNULL;
- }
-
-
- //------------------------------------------------------------------------------
- // Method: CreateShape
- // Origin: DrawEditor
- //
- // Description: This method creates the enumerated shape and returns a pointer to it.
- //------------------------------------------------------------------------------
-
- CShape* DrawEditor::CreateShape(Environment* ev, ODSShort shapeType, Rect shapeBounds)
- {
- SOM_Trace("DrawEditor","CreateShape");
-
- CShape* theShape = kODNULL;
-
- switch (shapeType)
- {
- case kRectShape:
- {
- theShape = new CRectangleShape();
- break;
- }
- case kOvalShape:
- {
- theShape = new COvalShape();
- break;
- }
-
- case kEmbeddingShape:
- {
- theShape = new CEmbeddingShape(this);
- break;
- }
- case kPolygonShape:
- {
- theShape = new CPolygonShape();
- ((CPolygonShape*)theShape)->SetPolygon(3);
- break;
- }
- /*
- case kLineShape:
- theShape = new CLineShape();
- break;
- */
- }
-
- // Set the bounding box
- if (theShape)
- theShape->SetBoundingBox(ev, shapeBounds);
-
- // return the shape
- return theShape;
- }
-
- //------------------------------------------------------------------------------
- // Method: SetPendingPublish
- // Origin: DrawEditor
- //
- // Description:
- //------------------------------------------------------------------------------
- void DrawEditor::SetPendingPublish(CPublishLink *link)
- {
- // This is only called after clearing the clipboard, so rather than call DeletePendingPublish
- // we can avoid the overhead of checking the clipboard that we've just cleared
-
- if (fPendingPublish && fPendingPublish->CanDelete())
- {
- // The setters for the two pending publish members should insure that they never
- // contain the same non-null reference
-
- ASSERT(fPendingPublish != fPendingDragPublish, kODErrAssertionFailed);
- delete fPendingPublish;
- }
-
- // fPendingDragPublish is only used when we have two different pending publishers
-
- if (fPendingDragPublish == link)
- fPendingDragPublish = kODNULL;
-
- fPendingPublish = link;
-
- }
-
-
- //------------------------------------------------------------------------------
- // Method: SetPendingDragPublish
- // Origin: DrawEditor
- //
- // Description:
- //------------------------------------------------------------------------------
- void DrawEditor::SetPendingDragPublish(CPublishLink *link)
- {
-
- if (fPendingDragPublish)
- if (fPendingDragPublish->CanDelete())
- delete fPendingDragPublish;
-
- // PendingDragPublish is only used when we need to have two distinct
- // publishers pending. If this is the same one as is already pending for the
- // clipboard, then just clear the previous reference in fPendingDragPublish
-
- if (link == fPendingPublish)
- fPendingDragPublish = NULL;
- else
- fPendingDragPublish = link;
- }
-
-
- //------------------------------------------------------------------------------
- // Method: DeletePendingPublish
- // Origin: DrawEditor
- //
- // Description:
- //------------------------------------------------------------------------------
- void DrawEditor::DeletePendingPublish(Environment* ev)
- {
- if (fPendingPublish != NULL)
- {
- ODClipboard* clipboard = GetSession(ev)->GetClipboard(ev);
-
- if (fPendingPublish->GetPendingID() == clipboard->GetUpdateID(ev))
- {
- ODStorageUnit* clipboardSU = clipboard->GetContentStorageUnit(ev);
- if (clipboardSU->Exists(ev, kODPropLinkSpec, (ODValueType) NULL, 0) == TRUE)
- {
- clipboardSU->Focus(ev, kODPropLinkSpec, kODPosUndefined, (ODValueType) NULL, 0, kODPosUndefined);
- clipboardSU->Remove(ev);
- }
- }
-
- if (fPendingPublish->CanDelete() && fPendingPublish != fPendingDragPublish)
- delete fPendingPublish;
-
- fPendingPublish = NULL;
- }
- }
-
-
- //------------------------------------------------------------------------------
- // Method: AddPublishLink
- // Origin: DrawEditor
- //
- // Description:
- //------------------------------------------------------------------------------
- void DrawEditor::AddPublishLink(CPublishLink *link)
- {
- fPublishLinks->AddLast(link);
- }
-
-
- //------------------------------------------------------------------------------
- // Method: RemovePublishLink
- // Origin: DrawEditor
- //
- // Description:
- //------------------------------------------------------------------------------
- void DrawEditor::RemovePublishLink(Environment* ev, CPublishLink *link)
- {
- fPublishLinks->Remove(link);
-
- if (link == fPendingPublish)
- this->DeletePendingPublish(ev);
- }
-
-
- //------------------------------------------------------------------------------
- // Method: CreateLink
- // Origin: ODPart
- //
- // Description:
- //------------------------------------------------------------------------------
- ODLinkSource* DrawEditor::CreateLink(Environment *ev, ODByteArray* data)
- {
- ODLinkSource* odLinkSource = kODNULL;
-
- LinkSpecData lsData = *((LinkSpecData*)(data->_buffer));
- ODUpdateID updateID = lsData.fUpdateID;
- CDragShapeCommand* dragCommand = lsData.fCommand;
-
- CPublishLink* pendingPublish = kODNULL;
-
- if (fPendingDragPublish && (fPendingDragPublish->GetPendingID() == updateID))
- pendingPublish = fPendingDragPublish;
- else if (fPendingPublish && (fPendingPublish->GetPendingID() == updateID))
- pendingPublish = fPendingPublish;
-
- // -- Make sure we got one.
- ASSERT_NOT_NULL(pendingPublish);
-
- if (!pendingPublish->IsPublished())
- {
- if (dragCommand)
- {
- dragCommand->CreateLink(ev, pendingPublish);
- }
- else
- {
- CCreateLinkCommand* command = new CCreateLinkCommand(this, pendingPublish);
- this->ExecuteCommand(ev, command);
- }
- }
- else
- {
- pendingPublish->ContentUpdated(ev, kODUnknownUpdate, kODTrue);
- }
-
- odLinkSource = pendingPublish->GetODLinkSource();
- odLinkSource->Acquire(ev);
- return odLinkSource;
- }
-
- //------------------------------------------------------------------------------
- // Method: AddSubscribeLink
- // Origin: DrawEditor
- //
- // Description:
- //------------------------------------------------------------------------------
- void DrawEditor::AddSubscribeLink(CSubscribeLink* link)
- {
- fSubscribeLinks->AddLast(link);
- }
-
- //------------------------------------------------------------------------------
- // Method: RemoveSubscribeLink
- // Origin: DrawEditor
- //
- // Description:
- //------------------------------------------------------------------------------
- void DrawEditor::RemoveSubscribeLink(CSubscribeLink* link)
- {
- fSubscribeLinks->Remove(link);
- }
-
-
- //------------------------------------------------------------------------------
- // Method: GetSubscribeLinks
- // Origin: DrawEditor
- //
- // Description:
- //------------------------------------------------------------------------------
- COrderedList* DrawEditor::GetSubscribeLinks()
- {
- return fSubscribeLinks;
- }
-
-
- //------------------------------------------------------------------------------
- // Method: GetPublishLinks
- // Origin: DrawEditor
- //
- // Description:
- //------------------------------------------------------------------------------
- COrderedList* DrawEditor::GetPublishLinks()
- {
- return fPublishLinks;
- }
-
- //------------------------------------------------------------------------------
- // Method: ContentUpdated
- // Origin: DrawEditor
- //
- // Description:
- //------------------------------------------------------------------------------
- void DrawEditor::ContentUpdated(Environment* ev, ODUpdateID id)
- {
-
- if (fLinkStatus == kODInLinkSource)
- {
- ODFrame* frame = this->GetFirstSourceFrame(ev);
- ASSERT_NOT_NULL(frame);
-
- if (!id)
- id = this->GetSession(ev)->UniqueUpdateID(ev);
-
- frame->ContentUpdated(ev, id);
- }
- }
-
-
- //------------------------------------------------------------------------------
- // Method: LinkUpdated
- // Origin: DrawEditor
- //
- // Description:
- //------------------------------------------------------------------------------
- void DrawEditor::LinkUpdated(Environment* ev, ODLink* odLink, ODUpdateID updateID)
- {
- ODBoolean updatedOne = kODFalse;
- COrderedList badLinkList;
-
- ODVolatile(updatedOne);
-
- // Notify all the subscribers that are destinations of the updated link
- COrdListIterator iter(fSubscribeLinks);
- for (CSubscribeLink* link = (CSubscribeLink*)iter.First(); iter.IsNotComplete(); link = (CSubscribeLink*)iter.Next())
- {
- if (odLink->IsEqualTo(ev, link->GetODLink()) && (link->IsRegistered()))
- {
- TRY
- link->LinkUpdated(ev, updateID);
- updatedOne = kODTrue;
-
- CATCH(kODErrCannotEstablishLink)
-
- // Cannot remove link from content model without busting this iterator, so
- // make a list. Theoretically there can be only one in this case but...
-
- badLinkList.AddLast(link);
-
- // This is supposed to alert user in this case, according to recipe.
- // Just beep for now.
-
- SysBeep(1);
- CATCH_ALL
- ENDTRY
-
- }
- }
-
- while (badLinkList.Count() != 0)
- {
- CSubscribeLink* badLink = (CSubscribeLink*)badLinkList.RemoveFirst();
- badLink->Unsubscribe(ev);
- delete badLink;
- }
-
- if (updatedOne)
- {
- this->ContentUpdated(ev, updateID);
- this->SetDirty(ev);
- }
- }
-
- //------------------------------------------------------------------------------
- // Method: GetSelection
- // Origin: DrawEditor
- //
- // Description:
- //------------------------------------------------------------------------------
- CSelection* DrawEditor::GetSelection()
- {
- return fSelection;
- }
-
-
- //------------------------------------------------------------------------------
- // Method: GetPendingPublish
- // Origin: DrawEditor
- //
- // Description:
- //------------------------------------------------------------------------------
- CPublishLink* DrawEditor::GetPendingPublish()
- {
- return fPendingPublish;
- }
-
- //------------------------------------------------------------------------------
- // Method: EditInLink
- // Origin: DrawEditor
- //
- // Description:
- //------------------------------------------------------------------------------
- void DrawEditor::EditInLink(Environment* ev, CSubscribeLink* link)
- {
- if (fLinkStatus == kODInLinkDestination)
- {
- ODFrame* frame = this->GetFirstSourceFrame(ev);
-
- ASSERT_NOT_NULL(frame);
-
- frame->EditInLink(ev);
- }
- else if (link)
- // Editing is being unambiguously prevented by a single destination link
- link->ShowCantEditDialog(ev);
- else
- this->ShowCantEditDialog(ev);
- }
-
- //------------------------------------------------------------------------------
- // Method: RevealLink
- // Origin: DrawEditor
- //
- // Description:
- //------------------------------------------------------------------------------
- void DrawEditor::RevealLink(Environment* ev, ODLinkSource* linkSource)
- {
- COrdListIterator ite(fPublishLinks);
- for (CPublishLink *link = (CPublishLink *)ite.First(); ite.IsNotComplete(); link = (CPublishLink *)ite.Next())
- {
- if (linkSource->IsEqualTo(ev, link->GetODLinkSource()))
- {
- // We've found the link, now we need to find a frame and activate the window and the frame.
-
- ODFrame* frame = this->GetFirstSourceFrame(ev);
-
- ASSERT_NOT_NULL(frame);
-
- // This code is adapted from HandleMouseEvent
- ODWindow* window = frame->AcquireWindow(ev);
- ASSERT_NOT_NULL(window);
-
- TRY
- // Activate inactive windows on the first mouse up event.
- if ( !window->IsActive(ev) )
- window->Select(ev);
-
- // Get our state information from the PartInfo of the frame.
- CFrameInfo* frameInfo = (CFrameInfo*) frame->GetPartInfo(ev);
-
- // If this frame is not the active one, activate it by requesting
- // the appropriate foci.
-
- if ( !frameInfo->IsFrameActive() )
- {
- if ( this->ActivateFrame(ev, frame) )
- {
- // Keep track of which facet was the last active for positioning
- // child windows. $$$$$ If we need to do this now, then we need a facet.
- // frameInfo->SetActiveFacet(facet);
- }
- }
- CATCH_ALL
- ENDTRY
-
- // select the link's content
- link->RevealLink(ev);
- break;
- }
- }
- }
-
-
- //------------------------------------------------------------------------------
- // Method: LinkStatusChanged
- // Origin: DrawEditor
- //
- // Description:
- //------------------------------------------------------------------------------
- void DrawEditor::LinkStatusChanged(Environment* ev, ODFrame* frame)
- {
- // cache whether we're in a link destination for conveience. This is optional
- fLinkStatus = frame->GetLinkStatus(ev);
-
- // Pass the status to our embedded shapes. Those in a subscriber or publisher of this part
- // should not be changed. One can just pass kODNotInLink, and ChangLinkStatus will insure
- // that the embedded frame reflects the status of it's containing frame.
-
- COrdListIterator iter(fShapeList);
- for (CShape * shape = (CShape*)iter.First(); iter.IsNotComplete(); shape = (CShape*)iter.Next())
- {
- if ((shape->GetShapeType() == kEmbeddingShape) && !shape->IsPublished() && ! shape->IsSubscribed())
- ((CEmbeddingShape*)shape)->ChangeLinkStatus(ev, kODNotInLink);
- }
- }
-
-
- //------------------------------------------------------------------------------
- // Method: ShowCantEditDialog
- // Origin: DrawEditor
- //
- // Description:
- //------------------------------------------------------------------------------
- void DrawEditor::ShowCantEditDialog(Environment* ev)
- {
- // Need to implement the HI specified dialog for when one cannot identify a specific link
- // which is preventing editing.
-
- SysBeep(1);
-
- }
-
-
- //------------------------------------------------------------------------------
- // Method: EditInLinkAttempted
- // Origin: DrawEditor
- //
- // Description:
- //------------------------------------------------------------------------------
- ODBoolean DrawEditor::EditInLinkAttempted(Environment* ev, ODFrame* frame)
- {
- CShape* shape = this->ShapeForFrame(ev, frame);
-
- CSubscribeLink *sLink = shape->GetSubscribeLink();
- if (shape && sLink)
- {
- sLink->ShowCantEditDialog(ev);
- return kODTrue;
- }
-
- return kODFalse; // shouldn't happen under the current linking model.
-
- }
-
-
- //------------------------------------------------------------------------------
- // Method: GetPendingDragPublish
- // Origin: DrawEditor
- //
- // Description:
- //------------------------------------------------------------------------------
- CPublishLink* DrawEditor::GetPendingDragPublish()
- {
- return fPendingDragPublish;
- }
-
-
-
-
-
-